def __init__(self, parent): attribs = (glcanvas.WX_GL_RGBA, glcanvas.WX_GL_DOUBLEBUFFER, glcanvas.WX_GL_DEPTH_SIZE, 24) glcanvas.GLCanvas.__init__(self, parent, -1, attribList = attribs) self.context = glcanvas.GLContext(self) self.setText = False self.parent = parent #Camera state variables self.size = self.GetClientSize() #self.camera = MouseSphericalCamera(self.size.x, self.size.y) self.camera = MousePolarCamera(self.size.width, self.size.height) #Main state variables self.MousePos = [0, 0] self.initiallyResized = False random.seed() #GUI State Variables self.GUIState = STATE_INTRO self.GUISubstate = -1 #Head Mesh self.headMesh = PolyMesh() self.headMesh.loadFile('NotreDameMedium.off') self.headMeshLowres = PolyMesh() self.headMeshLowres.loadFile('NotreDameLowres.off') self.styrofoamHead = PolyMesh() self.styrofoamHead.loadFile('StyrofoamHead.off') self.rotAngle = 0 self.zoom = 0 self.rotCount = 0 self.timelineCount = 0 #User's face self.userMesh = None self.colorUserMesh = None #ICP state variables self.ICPTransformation = np.zeros(0) self.ICPMutex = Lock() self.ICPThread = None self.bbox = self.headMesh.getBBox() self.camera.centerOnBBox(self.bbox, theta = -math.pi/2, phi = math.pi/2) self.zCenter = (self.bbox.zmax + self.bbox.zmin) / 2.0 self.GLinitialized = False #GL-related events wx.EVT_ERASE_BACKGROUND(self, self.processEraseBackgroundEvent) wx.EVT_SIZE(self, self.processSizeEvent) wx.EVT_PAINT(self, self.processPaintEvent) #Mouse Events wx.EVT_LEFT_DOWN(self, self.MouseDown) wx.EVT_LEFT_UP(self, self.MouseUp) wx.EVT_RIGHT_DOWN(self, self.MouseDown) wx.EVT_RIGHT_UP(self, self.MouseUp) wx.EVT_MIDDLE_DOWN(self, self.MouseDown) wx.EVT_MIDDLE_UP(self, self.MouseUp) wx.EVT_MOTION(self, self.MouseMotion) self.initGL()
def makeMeshSlow(self): if self.Xs.shape[2] == 0: return X = self.Xs[:, :, 0] Y = self.Ys[:, :, 0] Z = self.Zs[:, :, 0] mesh = PolyMesh() Vs = [[None] * self.Mask.shape[1] for i in range(self.Mask.shape[0])] #Add vertices for i in range(self.Mask.shape[0]): for j in range(self.Mask.shape[1]): if self.Mask[i, j]: Vs[i][j] = mesh.addVertex( np.array([X[i, j], Y[i, j], -Z[i, j]])) #Add triangles on grid for i in range(self.Mask.shape[0] - 1): print i for j in range(self.Mask.shape[1] - 1): if self.Mask[i, j] and self.Mask[i + 1, j] and self.Mask[i, j + 1]: mesh.addFace([Vs[i][j], Vs[i + 1][j], Vs[i][j + 1]]) if self.Mask[i + 1][j] and self.Mask[i + 1][ j + 1] and self.Mask[i][j + 1]: mesh.addFace( [Vs[i + 1][j], Vs[i + 1][j + 1], Vs[i][j + 1]]) mesh.updateTris() self.mesh = mesh
def __init__(self): #GLUT State variables self.GLUTwindow_height = 800 self.GLUTwindow_width = 800 self.GLUTmouse = [0, 0] self.GLUTButton = [0, 0, 0] self.GLUTModifiers = 0 self.keys = {} #Camera state variables #self.camera = Key6DOFCamera(Point3D(-0.230399, -0.0110676, -1.68559), Vector3D(0.135425, 0.0065054, 0.990766), Vector3D(-0.0479816, 0.998848, 0)) self.camera = Key6DOFCamera(Point3D(-1, 0, 0), Vector3D(1, 0, 0), Vector3D(0, 1, 0)) #Speeds of the UI controller self.dx = 0.1 self.dTheta = 0.1 self.mesh = PolyMesh() self.mesh.loadOffFile("meshes/homer.off") print "NVertices = %i, NEdges = %i, NFaces = %i"%(len(self.mesh.vertices), len(self.mesh.edges), len(self.mesh.faces)) self.initGL()
def OnLoadMesh(self, evt): dlg = wx.FileDialog(self, "Choose a file", ".", "", "OFF files (*.off)|*.off|TOFF files (*.toff)|*.toff|OBJ files (*.obj)|*.obj", wx.OPEN) if dlg.ShowModal() == wx.ID_OK: filename = dlg.GetFilename() dirname = dlg.GetDirectory() filepath = os.path.join(dirname, filename) print dirname self.glcanvas.mesh = PolyMesh() print "Loading mesh %s..."%filename self.glcanvas.mesh.loadFile(filepath) self.glcanvas.meshCentroid = self.glcanvas.mesh.getCentroid() self.glcanvas.meshPrincipalAxes = self.glcanvas.mesh.getPrincipalAxes() print "Finished loading mesh" print self.glcanvas.mesh self.glcanvas.initMeshBBox() self.glcanvas.Refresh() dlg.Destroy() return
def makeMeshSlow(self): if self.Xs.shape[2] == 0: return X = self.Xs[:, :, 0] Y = self.Ys[:, :, 0] Z = self.Zs[:, :, 0] mesh = PolyMesh() Vs = [[None]*self.Mask.shape[1] for i in range(self.Mask.shape[0])] #Add vertices for i in range(self.Mask.shape[0]): for j in range(self.Mask.shape[1]): if self.Mask[i, j]: Vs[i][j] = mesh.addVertex(np.array([X[i, j], Y[i, j], -Z[i, j]])) #Add triangles on grid for i in range(self.Mask.shape[0]-1): print i for j in range(self.Mask.shape[1]-1): if self.Mask[i, j] and self.Mask[i+1, j] and self.Mask[i, j+1]: mesh.addFace([Vs[i][j], Vs[i+1][j], Vs[i][j+1]]) if self.Mask[i+1][j] and self.Mask[i+1][j+1] and self.Mask[i][j+1]: mesh.addFace([Vs[i+1][j], Vs[i+1][j+1], Vs[i][j+1]]) mesh.updateTris() self.mesh = mesh
def __init__(self, xmeshfile, ymeshfile): #Do fast loading bypassing the mesh data structures since geometry #and topology are never changed xmesh = PolyMesh() print "Loading %s..."%xmeshfile (xmesh.VPos, xmesh.VColors, xmesh.ITris) = loadOffFileExternal(xmeshfile) xmesh.performDisplayUpdate(True) ymesh = PolyMesh() print "Loading %s..."%ymeshfile (ymesh.VPos, ymesh.VColors, ymesh.ITris) = loadOffFileExternal(ymeshfile) ymesh.performDisplayUpdate(True) app = wx.App() frame = ICPViewerFrame(None, -1, 'ICPViewer', xmesh, ymesh) frame.Show(True) app.MainLoop() app.Destroy()
def OnLoadFace(self, evt): dlg = wx.FileDialog(self, "Choose a file", ".", "", "OBJ files (*.obj)|*.obj|OFF files (*.off)|*.off", wx.OPEN) if dlg.ShowModal() == wx.ID_OK: filename = dlg.GetFilename() dirname = dlg.GetDirectory() filepath = os.path.join(dirname, filename) print dirname self.glcanvas.faceMesh = PolyMesh() print "Loading face %s..." % filename self.glcanvas.faceMesh.loadFile(filepath) print "Finished loading face\n %s" % self.glcanvas.faceMesh #print "Deleting all but largest connected component..." #self.glcanvas.faceMesh.deleteAllButLargestConnectedComponent() print self.glcanvas.faceMesh self.glcanvas.bbox = self.glcanvas.faceMesh.getBBox() print "Face BBox: %s\n" % self.glcanvas.bbox self.glcanvas.camera.centerOnBBox(self.glcanvas.bbox, theta=-math.pi / 2, phi=math.pi / 2) self.glcanvas.Refresh() dlg.Destroy() return
def makeMesh(self): if self.Xs.shape[2] == 0: return X = self.Xs[:, :, 0] Y = self.Ys[:, :, 0] Z = self.Zs[:, :, 0] mesh = PolyMesh() #Come up with vertex indices in the mask Mask = np.array(self.Mask, dtype=np.int32) nV = np.sum(Mask) Mask[self.Mask > 0] = np.arange(nV) + 1 Mask = Mask - 1 VPos = np.zeros((nV, 3)) VPos[:, 0] = X[self.Mask > 0] VPos[:, 1] = Y[self.Mask > 0] VPos[:, 2] = -Z[self.Mask > 0] #Add lower right triangle v1 = Mask[0:-1, 0:-1].flatten() v2 = Mask[1:, 0:-1].flatten() v3 = Mask[1:, 1:].flatten() N = v1.size ITris1 = np.concatenate((np.reshape(v1, [N, 1]), np.reshape( v2, [N, 1]), np.reshape(v3, [N, 1])), 1) #Add upper right triangle v1 = Mask[0:-1, 0:-1].flatten() v2 = Mask[1:, 1:].flatten() v3 = Mask[0:-1, 1:].flatten() N = v1.size ITris2 = np.concatenate((np.reshape(v1, [N, 1]), np.reshape( v2, [N, 1]), np.reshape(v3, [N, 1])), 1) ITris = np.concatenate((ITris1, ITris2), 0) #Only retain triangles which have all three points ITris = ITris[np.sum(ITris == -1, 1) == 0, :] mesh.VPos = VPos mesh.ITris = ITris mesh.VColors = 0.5 * np.ones(mesh.VPos.shape) mesh.updateNormalBuffer() mesh.VPosVBO = vbo.VBO(np.array(mesh.VPos, dtype=np.float32)) mesh.VNormalsVBO = vbo.VBO(np.array(mesh.VNormals, dtype=np.float32)) mesh.VColorsVBO = vbo.VBO(np.array(mesh.VColors, dtype=np.float32)) mesh.IndexVBO = vbo.VBO(mesh.ITris, target=GL_ELEMENT_ARRAY_BUFFER) mesh.needsDisplayUpdate = False self.mesh = mesh
# command line: model .off file | output EGI .off file import sys import os here = os.path.dirname(os.path.realpath(__file__)) sys.path.append(here + "/../S3DGLPy") sys.path.append(here + "/../") from Primitives3D import * from PolyMesh import * import numpy as np import matplotlib.pyplot as plt import ShapeStatistics as shp np.random.seed(40) #Replace 100 with some number you both agree on cmap = plt.get_cmap('jet') # color ramp resolution = 2 n = 10 m = PolyMesh() m.loadOffFileExternal(sys.argv[1]) #Load a mesh (Ps, Ns) = shp.samplePointCloud(m, 20000) #Sample 20,000 points and associated normals sphere = getSphereMesh(1, resolution) hist = shp.getEGIHistogram(Ps, Ns, sphere.VPos.T) hist = hist / np.max(hist) sphere.VColors = np.array(np.round(255.0*cmap(hist)[:, 0:3]), dtype=np.int64) sphere.saveOffFile(sys.argv[2], output255 = True) print hist
self.SwapBuffers() def doPCAGLPlot(Y, C, angles, stds, prefix): app = wx.PySimpleApp() frame = wx.Frame(None, wx.ID_ANY, "PCA GL Canvas", DEFAULT_POS, (800, 800)) g = PCAGLCanvas(frame, Y, C, angles, stds, prefix) frame.canvas = g frame.Show() app.MainLoop() app.Destroy() if __name__ == '__main__': NRandSamples = 10000 #You can tweak this number np.random.seed(100) #For repeatable results randomly sampling m = PolyMesh() m.loadFile("sword2.off") (Y, Ns) = m.randomlySamplePoints(NRandSamples) Y = Y.T Y = Y - np.mean(Y, 0)[None, :] C = np.array(Y) C = C - np.min(C, 0)[None, :] C = C/np.max(C, 0)[None, :] pca = PCA() Y = pca.fit_transform(Y) Y = Y/np.max(np.abs(Y)) plt.scatter(Y[:, 0], Y[:, 1], 20, C, edgecolors='none')
if v3: print "Updating %s to %g "%(v3.pos, v3.FMMDist) Q.put( (v3.FMMDist, v3) ) if e.f2: v3 = updateFMM(v1, v2, e.f2) if v3: print "Updating %s to %g "%(v3.pos, v3.FMMDist) Q.put( (v3.FMMDist, v3) ) v1.FMMType = FMM_BLACK_TYPE #Now copy over the distances to the matrix for k in range(0, N): D[i, k] = V[i].FMMDist return D if __name__ == '__main__': mesh = PolyMesh() v1 = mesh.addVertex(Point3D(0, 0, 0)) v2 = mesh.addVertex(Point3D(1, 0, 0)) v3 = mesh.addVertex(Point3D(1, 1, 0)) v4 = mesh.addVertex(Point3D(0, 1, 0)) v5 = mesh.addVertex(Point3D(1, 2, 0)) v6 = mesh.addVertex(Point3D(0, 2, 0)) mesh.addFace([v1, v2, v3]) mesh.addFace([v1, v3, v4]) mesh.addFace([v3, v5, v6]) mesh.addFace([v4, v3, v6]) mesh = getOctahedronMesh() getGeodesicDistancesFMM(mesh) mesh.saveOffFile("out.off")
def doPCAGLPlot(Y, C, angles, stds, prefix): app = wx.PySimpleApp() frame = wx.Frame(None, wx.ID_ANY, "PCA GL Canvas", DEFAULT_POS, (800, 800)) g = PCAGLCanvas(frame, Y, C, angles, stds, prefix) frame.canvas = g frame.Show() app.MainLoop() app.Destroy() if __name__ == '__main__': NRandSamples = 10000 #You can tweak this number np.random.seed(100) #For repeatable results randomly sampling m = PolyMesh() m.loadFile("sword2.off") (Y, Ns) = m.randomlySamplePoints(NRandSamples) Y = Y.T Y = Y - np.mean(Y, 0)[None, :] C = np.array(Y) C = C - np.min(C, 0)[None, :] C = C / np.max(C, 0)[None, :] pca = PCA() Y = pca.fit_transform(Y) Y = Y / np.max(np.abs(Y)) plt.scatter(Y[:, 0], Y[:, 1], 20, C, edgecolors='none') plt.axes().set_aspect('equal', 'datalim')
glutAddSubMenu("ICP Step By Step", stepByStepMenu) glutAddSubMenu("ICP Algorithm Full", icpMenu) glutAttachMenu(GLUT_RIGHT_BUTTON) glutMainLoop() if __name__ == '__main__': if len(sys.argv) < 3: print "Usage: python ICPViewerGLUT.py <mesh to align file> <target mesh file> [Maximum Number of Iterations] [Output File Prefix]" sys.exit(0) (xmeshfile, ymeshfile) = (sys.argv[1], sys.argv[2]) MaxIters = 200 if len(argv) > 3: MaxIters = int(argv[3]) outputPrefix = "" if len(argv) > 4: outputPrefix = argv[4] xmesh = PolyMesh() print "Loading %s..." % xmeshfile (xmesh.VPos, xmesh.VColors, xmesh.ITris) = loadOffFileExternal(xmeshfile) xmesh.performDisplayUpdate(True) ymesh = PolyMesh() print "Loading %s..." % ymeshfile (ymesh.VPos, ymesh.VColors, ymesh.ITris) = loadOffFileExternal(ymeshfile) ymesh.performDisplayUpdate(True) viewer = ICPViewerCanvas(xmesh, ymesh, MaxIters, outputPrefix) viewer.initGL()
class Viewer(object): def __init__(self): #GLUT State variables self.GLUTwindow_height = 800 self.GLUTwindow_width = 800 self.GLUTmouse = [0, 0] self.GLUTButton = [0, 0, 0] self.GLUTModifiers = 0 self.keys = {} #Camera state variables #self.camera = Key6DOFCamera(Point3D(-0.230399, -0.0110676, -1.68559), Vector3D(0.135425, 0.0065054, 0.990766), Vector3D(-0.0479816, 0.998848, 0)) self.camera = Key6DOFCamera(Point3D(-1, 0, 0), Vector3D(1, 0, 0), Vector3D(0, 1, 0)) #Speeds of the UI controller self.dx = 0.1 self.dTheta = 0.1 self.mesh = PolyMesh() self.mesh.loadOffFile("meshes/homer.off") print "NVertices = %i, NEdges = %i, NFaces = %i"%(len(self.mesh.vertices), len(self.mesh.edges), len(self.mesh.faces)) self.initGL() def GLUTResize(self, w, h): glViewport(0, 0, w, h) self.GLUTwindow_width = w self.GLUTwindow_height = h glutPostRedisplay() def GLUTRedraw(self): #Set up projection matrix glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(180.0*self.camera.yfov/M_PI, float(self.GLUTwindow_width)/self.GLUTwindow_height, 0.01, 100.0) #Set up modelview matrix self.camera.gotoCameraFrame() glClearColor(0.0, 0.0, 0.0, 0.0) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) #print gluErrorString(glGetError()) glLightfv(GL_LIGHT0, GL_POSITION, [3.0, 4.0, 5.0, 0.0]); glLightfv(GL_LIGHT1, GL_POSITION, [-3.0, -2.0, -3.0, 0.0]); glEnable(GL_LIGHTING) glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, [0.8, 0.8, 0.8, 1.0]); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, [0.2, 0.2, 0.2, 1.0]) glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, 64) glBegin(GL_TRIANGLES) glVertex3f(-1, 0, 0) glVertex3f(1, 0, 0) glVertex3f(0.5, 1, 0) glVertex3f(0, -1, 0) glVertex3f(0, 1, 0) glVertex3f(0, 0, 1) glEnd() self.mesh.renderGL() glutSwapBuffers() def handleMouseStuff(self, x, y): y = self.GLUTwindow_height - y self.GLUTmouse[0] = x self.GLUTmouse[1] = y self.GLUTmodifiers = glutGetModifiers() def GLUTKeyboard(self, key, x, y): self.handleMouseStuff(x, y) self.camera.keys[key] = True glutPostRedisplay() def GLUTKeyboardUp(self, key, x, y): self.handleMouseStuff(x, y) self.camera.keys[key] = False glutPostRedisplay() def GLUTSpecial(self, key, x, y): self.handleMouseStuff(x, y) self.camera.keys[key] = True glutPostRedisplay() def GLUTSpecialUp(self, key, x, y): self.handleMouseStuff(x, y) self.camera.keys[key] = False glutPostRedisplay() def GLUTMouse(self, button, state, x, y): self.handleMouseStuff(x, y) glutPostRedisplay() def GLUTMotion(self, x, y): self.handleMouseStuff(x, y) glutPostRedisplay() def initGL(self): glutInit('') glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH) glutInitWindowSize(self.GLUTwindow_width, self.GLUTwindow_height) glutInitWindowPosition(50, 50) glutCreateWindow('Viewer') glutReshapeFunc(self.GLUTResize) glutDisplayFunc(self.GLUTRedraw) glutKeyboardFunc(self.GLUTKeyboard) glutKeyboardUpFunc(self.GLUTKeyboardUp) glutSpecialFunc(self.GLUTSpecial) glutSpecialUpFunc(self.GLUTSpecialUp) glutMouseFunc(self.GLUTMouse) glutMotionFunc(self.GLUTMotion) glutTimerFunc(self.camera.minTimestepLen, self.camera.handleUserInput, 1) glLightModelfv(GL_LIGHT_MODEL_AMBIENT, [0.2, 0.2, 0.2, 1.0]) glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE) glLightfv(GL_LIGHT0, GL_DIFFUSE, [1.0, 1.0, 1.0, 1.0]) glEnable(GL_LIGHT0) glLightfv(GL_LIGHT1, GL_DIFFUSE, [0.5, 0.5, 0.5, 1.0]) glEnable(GL_LIGHT1) glEnable(GL_NORMALIZE) glEnable(GL_LIGHTING) glEnable(GL_DEPTH_TEST) glutMainLoop()
def ReadRecurse(self, filename='', EMMaterials={}, OpticalMaterials={}, RadiosityMaterials={}, EMParentNode=None, XMLNode=None): if (len(filename) > 0): tree = ET.parse(filename) XMLNode = tree.getroot() #Load in materials if XMLNode.find('OpticalMaterials') != None: node = XMLNode.find('OpticalMaterials') for mat in node.getchildren(): name = mat.get("name") args = ["ka", "kd", "ks", "kt", "emission"] for arg in args: if mat.get(arg) == None: print "Error: No %s defined in optical material %s" % ( arg, name) return ka = [float(i) for i in mat.get("ka").split()] kd = [float(i) for i in mat.get("ks").split()] ks = [float(i) for i in mat.get("ka").split()] kt = [float(i) for i in mat.get("kt").split()] emission = [float(i) for i in mat.get("emission").split()] OpticalMaterials[name] = OpticalMaterial( RGB3D(ka[0], ka[1], ka[2]), RGB3D(kd[0], kd[1], kd[2]), RGB3D(ks[0], ks[1], ks[2]), RGB3D(kt[0], kt[1], kt[2]), RGB3D(emission[0], emission[1], emission[2])) if XMLNode.find('EMMaterials') != None: node = XMLNode.find('EMMaterials') for mat in node.getchildren(): name = mat.get("name") args = ["R", "T"] for arg in args: if mat.get(arg) == None: print "Error: No %s defined in EM material %s" % ( arg, name) return R = float(mat.get("R")) T = float(mat.get("T")) EMMaterials[name] = EMMaterial(R, T) if XMLNode.find('RadiosityMaterials') != None: node = XMLNode.find('RadiosityMaterials') for mat in node.getchildren(): name = mat.get("name") #arguments are emission and reflectance args = ["em", "p"] for arg in args: if mat.get(arg) == None: print "Error: No %s defined in Radiosity material %s" % ( arg, name) return [R, G, B] = [float(i) for i in mat.get("em").split()] em = RGB3D(R, G, B) [R, G, B] = [float(i) for i in mat.get("p").split()] p = RGB3D(R, G, B) RadiosityMaterials[name] = RadiosityMaterial(em, p) for currNode in XMLNode.getchildren(): EMMat = EMMaterial() OpticalMat = OpticalMaterial() RadiosityMat = RadiosityMaterial() #Get materials (if specified...otherwise use defaults) if currNode.tag in ["tri", "box", "rect", "mesh"]: if currNode.get("em") != None: EMMat = EMMaterials[currNode.get("em")] if currNode.get("om") != None: OpticalMat = OpticalMaterials[currNode.get("om")] if currNode.get("rm") != None: RadiosityMat = RadiosityMaterials[currNode.get("rm")] #Get transformation matrix (if it exists...otherwise use identity matrix) matrix = Matrix4() if currNode.tag in ["tri", "box", "mesh", "node", "include"]: if currNode.text != None: m = [float(i) for i in currNode.text.split()] if len(m) == 16: matrix = Matrix4(m) elif len(m) != 0: print "Invalid transformation matrix specification %s" % ( currNode.text) return #Now process tag-specific elements if currNode.tag == "tri": args = ["P0", "P1", "P2"] for arg in args: if currNode.get(arg) == None: print "Error: No %s defined in triangle" % (arg) return P0args = [float(i) for i in currNode.get("P0").split()] P1args = [float(i) for i in currNode.get("P1").split()] P2args = [float(i) for i in currNode.get("P2").split()] P0 = Point3D(P0args[0], P0args[1], P0args[2]) P1 = Point3D(P1args[0], P1args[1], P1args[2]) P2 = Point3D(P2args[0], P2args[1], P2args[2]) mesh = PolyMesh() [V0, V1, V2] = [ mesh.addVertex(P0), mesh.addVertex(P1), mesh.addVertex(P2) ] mesh.addFace([V0, V1, V2]) sceneNode = EMNode(EMParentNode, mesh, matrix, EMMat, OpticalMat, RadiosityMat) EMParentNode.children.append(sceneNode) elif currNode.tag == "box": args = ["length", "width", "height"] for arg in args: if currNode.get(arg) == None: print "Error: No %s defined in box" % (arg) return L = float(currNode.get("length")) #Length in z W = float(currNode.get("width")) #Width in x H = float(currNode.get("height")) #Height in y C = Point3D(0, 0, 0) stepSize = -1 #Center is an optional argument if currNode.get("center") != None: CPoints = [ float(i) for i in currNode.get("center").split() ] #Center of box C = Point3D(CPoints[0], CPoints[1], CPoints[2]) if currNode.get("stepSize") != None: stepSize = float(currNode.get("stepSize")) mesh = getBoxMesh(L, W, H, C, stepSize) if currNode.get("flipNormals") != None: if int(currNode.get("flipNormals")) == 1: mesh.flipNormals() sceneNode = EMNode(EMParentNode, mesh, matrix, EMMat, OpticalMat, RadiosityMat) EMParentNode.children.append(sceneNode) elif currNode.tag == "rect": args = ["P0", "P1", "P2", "P3"] for arg in args: if currNode.get(arg) == None: print "Error: No %s defined in rect" % (arg) return P0args = [float(i) for i in currNode.get("P0").split()] P1args = [float(i) for i in currNode.get("P1").split()] P2args = [float(i) for i in currNode.get("P2").split()] P3args = [float(i) for i in currNode.get("P3").split()] P0 = Point3D(P0args[0], P0args[1], P0args[2]) P1 = Point3D(P1args[0], P1args[1], P1args[2]) P2 = Point3D(P2args[0], P2args[1], P2args[2]) P3 = Point3D(P3args[0], P3args[1], P3args[2]) stepSize = -1 if currNode.get("stepSize") != None: stepSize = float(currNode.get("stepSize")) mesh = getRectMesh(P0, P1, P2, P3, stepSize) sceneNode = EMNode(EMParentNode, mesh, matrix, EMMat, OpticalMat, RadiosityMat) EMParentNode.children.append(sceneNode) elif currNode.tag == "mesh": args = ["filename"] for arg in args: if currNode.get(arg) == None: print "Error: No %s defined in mesh" % (arg) return meshfilename = currNode.get("filename") mesh = PolyMesh() mesh.loadFile(meshfilename) if currNode.get("flipNormals") != None: if int(currNode.get("flipNormals")) == 1: mesh.flipNormals() sceneNode = EMNode(EMParentNode, mesh, matrix, EMMat, OpticalMat, RadiosityMat) EMParentNode.children.append(sceneNode) elif currNode.tag == "node": #This is a transformation node in the graph sceneNode = EMNode(parent=EMParentNode, transformation=matrix) EMParentNode.children.append(sceneNode) #Now recursively add the branch in this node self.ReadRecurse('', EMMaterials, OpticalMaterials, RadiosityMaterials, sceneNode, currNode) elif currNode.tag == "include": #Recursively include another scene file as a branch in this tree if currNode.get("filename") == None: print "Error: No filename defined for included scene" return nextfilename = currNode.get("filename") sceneNode = EMNode(parent=EMParentNode, transformation=matrix) EMParentNode.children.append(sceneNode) self.ReadRecurse(nextfilename, {}, {}, {}, sceneNode, None) elif currNode.tag == "Source": if currNode.get("pos") == None: print "Error: No position defined for EM Source" return coords = [float(i) for i in currNode.get("pos").split()] self.Source = Point3D(coords[0], coords[1], coords[2]) elif currNode.tag == "Receiver": if currNode.get("pos") == None: print "Error: No position defined for EM Receiver" return coords = [float(i) for i in currNode.get("pos").split()] self.Receiver = Point3D(coords[0], coords[1], coords[2]) else: if not (currNode.tag in [ "EMMaterials", "OpticalMaterials", "RadiosityMaterials" ]): #Checking to make sure it's a string handles the case #where it's a comment if type(currNode.tag) is str: print "Unrecognized tag %s" % currNode.tag
def makeMesh(self): if self.Xs.shape[2] == 0: return X = self.Xs[:, :, 0] Y = self.Ys[:, :, 0] Z = self.Zs[:, :, 0] mesh = PolyMesh() #Come up with vertex indices in the mask Mask = np.array(self.Mask, dtype=np.int32) nV = np.sum(Mask) Mask[self.Mask > 0] = np.arange(nV) + 1 Mask = Mask - 1 VPos = np.zeros((nV, 3)) VPos[:, 0] = X[self.Mask > 0] VPos[:, 1] = Y[self.Mask > 0] VPos[:, 2] = -Z[self.Mask > 0] #Add lower right triangle v1 = Mask[0:-1, 0:-1].flatten() v2 = Mask[1:, 0:-1].flatten() v3 = Mask[1:, 1:].flatten() N = v1.size ITris1 = np.concatenate((np.reshape(v1, [N, 1]), np.reshape(v2, [N, 1]), np.reshape(v3, [N, 1])), 1) #Add upper right triangle v1 = Mask[0:-1, 0:-1].flatten() v2 = Mask[1:, 1:].flatten() v3 = Mask[0:-1, 1:].flatten() N = v1.size ITris2 = np.concatenate((np.reshape(v1, [N, 1]), np.reshape(v2, [N, 1]), np.reshape(v3, [N, 1])), 1) ITris = np.concatenate((ITris1, ITris2), 0) #Only retain triangles which have all three points ITris = ITris[np.sum(ITris == -1, 1) == 0, :] mesh.VPos = VPos mesh.ITris = ITris mesh.VColors = 0.5*np.ones(mesh.VPos.shape) mesh.updateNormalBuffer() mesh.VPosVBO = vbo.VBO(np.array(mesh.VPos, dtype=np.float32)) mesh.VNormalsVBO = vbo.VBO(np.array(mesh.VNormals, dtype=np.float32)) mesh.VColorsVBO = vbo.VBO(np.array(mesh.VColors, dtype=np.float32)) mesh.IndexVBO = vbo.VBO(mesh.ITris, target=GL_ELEMENT_ARRAY_BUFFER) mesh.needsDisplayUpdate = False self.mesh = mesh
def ReadRecurse( self, filename="", EMMaterials={}, OpticalMaterials={}, RadiosityMaterials={}, EMParentNode=None, XMLNode=None ): if len(filename) > 0: tree = ET.parse(filename) XMLNode = tree.getroot() # Load in materials if XMLNode.find("OpticalMaterials") != None: node = XMLNode.find("OpticalMaterials") for mat in node.getchildren(): name = mat.get("name") args = ["ka", "kd", "ks", "kt", "emission"] for arg in args: if mat.get(arg) == None: print "Error: No %s defined in optical material %s" % (arg, name) return ka = [float(i) for i in mat.get("ka").split()] kd = [float(i) for i in mat.get("ks").split()] ks = [float(i) for i in mat.get("ka").split()] kt = [float(i) for i in mat.get("kt").split()] emission = [float(i) for i in mat.get("emission").split()] OpticalMaterials[name] = OpticalMaterial( RGB3D(ka[0], ka[1], ka[2]), RGB3D(kd[0], kd[1], kd[2]), RGB3D(ks[0], ks[1], ks[2]), RGB3D(kt[0], kt[1], kt[2]), RGB3D(emission[0], emission[1], emission[2]), ) if XMLNode.find("EMMaterials") != None: node = XMLNode.find("EMMaterials") for mat in node.getchildren(): name = mat.get("name") args = ["R", "T"] for arg in args: if mat.get(arg) == None: print "Error: No %s defined in EM material %s" % (arg, name) return R = float(mat.get("R")) T = float(mat.get("T")) EMMaterials[name] = EMMaterial(R, T) if XMLNode.find("RadiosityMaterials") != None: node = XMLNode.find("RadiosityMaterials") for mat in node.getchildren(): name = mat.get("name") # arguments are emission and reflectance args = ["em", "p"] for arg in args: if mat.get(arg) == None: print "Error: No %s defined in Radiosity material %s" % (arg, name) return [R, G, B] = [float(i) for i in mat.get("em").split()] em = RGB3D(R, G, B) [R, G, B] = [float(i) for i in mat.get("p").split()] p = RGB3D(R, G, B) RadiosityMaterials[name] = RadiosityMaterial(em, p) for currNode in XMLNode.getchildren(): EMMat = EMMaterial() OpticalMat = OpticalMaterial() RadiosityMat = RadiosityMaterial() # Get materials (if specified...otherwise use defaults) if currNode.tag in ["tri", "box", "rect", "mesh"]: if currNode.get("em") != None: EMMat = EMMaterials[currNode.get("em")] if currNode.get("om") != None: OpticalMat = OpticalMaterials[currNode.get("om")] if currNode.get("rm") != None: RadiosityMat = RadiosityMaterials[currNode.get("rm")] # Get transformation matrix (if it exists...otherwise use identity matrix) matrix = Matrix4() if currNode.tag in ["tri", "box", "mesh", "node", "include"]: if currNode.text != None: m = [float(i) for i in currNode.text.split()] if len(m) == 16: matrix = Matrix4(m) elif len(m) != 0: print "Invalid transformation matrix specification %s" % (currNode.text) return # Now process tag-specific elements if currNode.tag == "tri": args = ["P0", "P1", "P2"] for arg in args: if currNode.get(arg) == None: print "Error: No %s defined in triangle" % (arg) return P0args = [float(i) for i in currNode.get("P0").split()] P1args = [float(i) for i in currNode.get("P1").split()] P2args = [float(i) for i in currNode.get("P2").split()] P0 = Point3D(P0args[0], P0args[1], P0args[2]) P1 = Point3D(P1args[0], P1args[1], P1args[2]) P2 = Point3D(P2args[0], P2args[1], P2args[2]) mesh = PolyMesh() [V0, V1, V2] = [mesh.addVertex(P0), mesh.addVertex(P1), mesh.addVertex(P2)] mesh.addFace([V0, V1, V2]) sceneNode = EMNode(EMParentNode, mesh, matrix, EMMat, OpticalMat, RadiosityMat) EMParentNode.children.append(sceneNode) elif currNode.tag == "box": args = ["length", "width", "height"] for arg in args: if currNode.get(arg) == None: print "Error: No %s defined in box" % (arg) return L = float(currNode.get("length")) # Length in z W = float(currNode.get("width")) # Width in x H = float(currNode.get("height")) # Height in y C = Point3D(0, 0, 0) stepSize = -1 # Center is an optional argument if currNode.get("center") != None: CPoints = [float(i) for i in currNode.get("center").split()] # Center of box C = Point3D(CPoints[0], CPoints[1], CPoints[2]) if currNode.get("stepSize") != None: stepSize = float(currNode.get("stepSize")) mesh = getBoxMesh(L, W, H, C, stepSize) if currNode.get("flipNormals") != None: if int(currNode.get("flipNormals")) == 1: mesh.flipNormals() sceneNode = EMNode(EMParentNode, mesh, matrix, EMMat, OpticalMat, RadiosityMat) EMParentNode.children.append(sceneNode) elif currNode.tag == "rect": args = ["P0", "P1", "P2", "P3"] for arg in args: if currNode.get(arg) == None: print "Error: No %s defined in rect" % (arg) return P0args = [float(i) for i in currNode.get("P0").split()] P1args = [float(i) for i in currNode.get("P1").split()] P2args = [float(i) for i in currNode.get("P2").split()] P3args = [float(i) for i in currNode.get("P3").split()] P0 = Point3D(P0args[0], P0args[1], P0args[2]) P1 = Point3D(P1args[0], P1args[1], P1args[2]) P2 = Point3D(P2args[0], P2args[1], P2args[2]) P3 = Point3D(P3args[0], P3args[1], P3args[2]) stepSize = -1 if currNode.get("stepSize") != None: stepSize = float(currNode.get("stepSize")) mesh = getRectMesh(P0, P1, P2, P3, stepSize) sceneNode = EMNode(EMParentNode, mesh, matrix, EMMat, OpticalMat, RadiosityMat) EMParentNode.children.append(sceneNode) elif currNode.tag == "mesh": args = ["filename"] for arg in args: if currNode.get(arg) == None: print "Error: No %s defined in mesh" % (arg) return meshfilename = currNode.get("filename") mesh = PolyMesh() mesh.loadFile(meshfilename) if currNode.get("flipNormals") != None: if int(currNode.get("flipNormals")) == 1: mesh.flipNormals() sceneNode = EMNode(EMParentNode, mesh, matrix, EMMat, OpticalMat, RadiosityMat) EMParentNode.children.append(sceneNode) elif currNode.tag == "node": # This is a transformation node in the graph sceneNode = EMNode(parent=EMParentNode, transformation=matrix) EMParentNode.children.append(sceneNode) # Now recursively add the branch in this node self.ReadRecurse("", EMMaterials, OpticalMaterials, RadiosityMaterials, sceneNode, currNode) elif currNode.tag == "include": # Recursively include another scene file as a branch in this tree if currNode.get("filename") == None: print "Error: No filename defined for included scene" return nextfilename = currNode.get("filename") sceneNode = EMNode(parent=EMParentNode, transformation=matrix) EMParentNode.children.append(sceneNode) self.ReadRecurse(nextfilename, {}, {}, {}, sceneNode, None) elif currNode.tag == "Source": if currNode.get("pos") == None: print "Error: No position defined for EM Source" return coords = [float(i) for i in currNode.get("pos").split()] self.Source = Point3D(coords[0], coords[1], coords[2]) elif currNode.tag == "Receiver": if currNode.get("pos") == None: print "Error: No position defined for EM Receiver" return coords = [float(i) for i in currNode.get("pos").split()] self.Receiver = Point3D(coords[0], coords[1], coords[2]) else: if not (currNode.tag in ["EMMaterials", "OpticalMaterials", "RadiosityMaterials"]): # Checking to make sure it's a string handles the case # where it's a comment if type(currNode.tag) is str: print "Unrecognized tag %s" % currNode.tag
def __init__(self, parent): attribs = (glcanvas.WX_GL_RGBA, glcanvas.WX_GL_DOUBLEBUFFER, glcanvas.WX_GL_DEPTH_SIZE, 24) glcanvas.GLCanvas.__init__(self, parent, -1, attribList=attribs) self.context = glcanvas.GLContext(self) self.setText = False self.parent = parent #Camera state variables self.size = self.GetClientSize() #self.camera = MouseSphericalCamera(self.size.x, self.size.y) self.camera = MousePolarCamera(self.size.width, self.size.height) #Main state variables self.MousePos = [0, 0] self.initiallyResized = False random.seed() #GUI State Variables self.GUIState = STATE_INTRO self.GUISubstate = -1 #Head Mesh self.headMesh = PolyMesh() self.headMesh.loadFile('NotreDameMedium.off') self.headMeshLowres = PolyMesh() self.headMeshLowres.loadFile('NotreDameLowres.off') self.styrofoamHead = PolyMesh() self.styrofoamHead.loadFile('StyrofoamHead.off') self.rotAngle = 0 self.zoom = 0 self.rotCount = 0 self.timelineCount = 0 #User's face self.userMesh = None self.colorUserMesh = None #ICP state variables self.ICPTransformation = np.zeros(0) self.ICPMutex = Lock() self.ICPThread = None self.bbox = self.headMesh.getBBox() self.camera.centerOnBBox(self.bbox, theta=-math.pi / 2, phi=math.pi / 2) self.zCenter = (self.bbox.zmax + self.bbox.zmin) / 2.0 self.GLinitialized = False #GL-related events wx.EVT_ERASE_BACKGROUND(self, self.processEraseBackgroundEvent) wx.EVT_SIZE(self, self.processSizeEvent) wx.EVT_PAINT(self, self.processPaintEvent) #Mouse Events wx.EVT_LEFT_DOWN(self, self.MouseDown) wx.EVT_LEFT_UP(self, self.MouseUp) wx.EVT_RIGHT_DOWN(self, self.MouseDown) wx.EVT_RIGHT_UP(self, self.MouseUp) wx.EVT_MIDDLE_DOWN(self, self.MouseDown) wx.EVT_MIDDLE_UP(self, self.MouseUp) wx.EVT_MOTION(self, self.MouseMotion) self.initGL()
globalMenu = glutCreateMenu(self.dmenu) glutAddSubMenu("ICP Step By Step", stepByStepMenu) glutAddSubMenu("ICP Algorithm Full", icpMenu) glutAttachMenu(GLUT_RIGHT_BUTTON) glutMainLoop() if __name__ == '__main__': if len(sys.argv) < 3: print "Usage: python ICPViewerGLUT.py <mesh to align file> <target mesh file> [Maximum Number of Iterations] [Output File Prefix]" sys.exit(0) (xmeshfile, ymeshfile) = (sys.argv[1], sys.argv[2]) MaxIters = 200 if len(argv) > 3: MaxIters = int(argv[3]) outputPrefix = "" if len(argv) > 4: outputPrefix = argv[4] xmesh = PolyMesh() print "Loading %s..."%xmeshfile (xmesh.VPos, xmesh.VColors, xmesh.ITris) = loadOffFileExternal(xmeshfile) xmesh.performDisplayUpdate(True) ymesh = PolyMesh() print "Loading %s..."%ymeshfile (ymesh.VPos, ymesh.VColors, ymesh.ITris) = loadOffFileExternal(ymeshfile) ymesh.performDisplayUpdate(True) viewer = ICPViewerCanvas(xmesh, ymesh, MaxIters, outputPrefix) viewer.initGL()
if(correct >= NPerClass-1): #if we've found all correct shapes in class, no need to proceed, break break rIn += 1 #increment row counter i.e. move to next row PR = PR/len(D) #divide all precision values by number of rows i.e find average as summation of precision values/number of precision values return PR ######################################################### ## MAIN TESTS ## ######################################################### #sys.exit("Not executing rest of code") if __name__ == '__main__': m = PolyMesh() m.loadFile("models_off/biplane0.off") #Load a mesh (Ps, Ns) = samplePointCloud(m, 5) #Sample 20,000 points and associated normals exportPointCloud(Ps, Ns, "biplane.pts") #Export point cloud #TESTING GET-SHAPE-HISTOGRAM #histogram1 = getShapeHistogram(Ps, Ns, 21, 3) #print histogram1 #print bins1 #plt.bar(bins1, histogram1, width=3.0/21*0.9) #plt.show() #TESTING GET-2D-HISTOGRAM #DMax = 4 #NBins = 20 #NSamples = 5
elif e.numAttachedFaces() == 1: foundNext = True loop.append(v) break if not foundNext and not finished: print "Warning: Unable to close hole" break print "Found hole of size %i" % len(loop) return loop if __name__ == '__main__': if len(argv) < 3: print "Usage: AddFaceBack [inputMesh] [outputMesh]" exit(0) mesh = PolyMesh() mesh.loadFile(argv[1]) hole = findHole(mesh) (Axis1, Axis2, Axis3, maxProj, minProj, axes) = mesh.getPrincipalAxes() Centroid = mesh.getCentroid() #Copy over the hole boundary points to a numpy array NH = len(hole) VH = np.zeros((NH, 3)) for i in range(NH): thisP = hole[i].pos VH[i, :] = np.array([thisP.x, thisP.y, thisP.z]) #Transform the mesh and the the coordinate system of the principal axes of the mesh #where the Z coordinate can be ignored (since it's the axis of least variation) Trans = np.eye(4) Trans[0, 3] = -Centroid.x
import numpy as np from PolyMesh import * if __name__ == '__main__': m = PolyMesh() m.loadFile("homer.off") m.performDisplayUpdate() m2 = PolyMesh() (m2.VPos, m2.VColors, m2.ITris) = loadOffFileExternal("homer.off") m2.performDisplayUpdate(True) print m.EdgeLines print "\n\n\n" print m2.EdgeLines
class MeshViewerCanvas(glcanvas.GLCanvas): def __init__(self, parent): attribs = (glcanvas.WX_GL_RGBA, glcanvas.WX_GL_DOUBLEBUFFER, glcanvas.WX_GL_DEPTH_SIZE, 24) glcanvas.GLCanvas.__init__(self, parent, -1, attribList = attribs) self.context = glcanvas.GLContext(self) self.setText = False self.parent = parent #Camera state variables self.size = self.GetClientSize() #self.camera = MouseSphericalCamera(self.size.x, self.size.y) self.camera = MousePolarCamera(self.size.width, self.size.height) #Main state variables self.MousePos = [0, 0] self.initiallyResized = False random.seed() #GUI State Variables self.GUIState = STATE_INTRO self.GUISubstate = -1 #Head Mesh self.headMesh = PolyMesh() self.headMesh.loadFile('NotreDameMedium.off') self.headMeshLowres = PolyMesh() self.headMeshLowres.loadFile('NotreDameLowres.off') self.styrofoamHead = PolyMesh() self.styrofoamHead.loadFile('StyrofoamHead.off') self.rotAngle = 0 self.zoom = 0 self.rotCount = 0 self.timelineCount = 0 #User's face self.userMesh = None self.colorUserMesh = None #ICP state variables self.ICPTransformation = np.zeros(0) self.ICPMutex = Lock() self.ICPThread = None self.bbox = self.headMesh.getBBox() self.camera.centerOnBBox(self.bbox, theta = -math.pi/2, phi = math.pi/2) self.zCenter = (self.bbox.zmax + self.bbox.zmin) / 2.0 self.GLinitialized = False #GL-related events wx.EVT_ERASE_BACKGROUND(self, self.processEraseBackgroundEvent) wx.EVT_SIZE(self, self.processSizeEvent) wx.EVT_PAINT(self, self.processPaintEvent) #Mouse Events wx.EVT_LEFT_DOWN(self, self.MouseDown) wx.EVT_LEFT_UP(self, self.MouseUp) wx.EVT_RIGHT_DOWN(self, self.MouseDown) wx.EVT_RIGHT_UP(self, self.MouseUp) wx.EVT_MIDDLE_DOWN(self, self.MouseDown) wx.EVT_MIDDLE_UP(self, self.MouseUp) wx.EVT_MOTION(self, self.MouseMotion) self.initGL() def drawText(self, x, y, text, size = 1, font = GLUT_BITMAP_TIMES_ROMAN_24): glDisable(GL_LIGHTING) glDisable(GL_DEPTH_TEST) glMatrixMode(GL_PROJECTION) glLoadIdentity() gluOrtho2D(0, self.size[0], 0, self.size[1]) glMatrixMode(GL_MODELVIEW) glLoadIdentity() glColor3f(1, 0, 0) glRasterPos2f(x, y) glPushMatrix() #for i in range(len(text)): # glutBitmapCharacter(font, ord(text[i])) glPopMatrix() glEnable(GL_LIGHTING) glEnable(GL_DEPTH_TEST) def startButtonHandler(self, evt): print "Starting Face capture..." if not self.setText: self.titleText.SetLabelText("Capturing Face...") self.setText = True #os.popen3("SingleFace.exe") #Captures the face process = subprocess.Popen("SingleFace", shell=True, stdout=subprocess.PIPE) process.wait() print "FINISHED CAPTURE" extractMeshFiles() #Convert the captured data to a triangulated mesh self.userMesh = LaplacianMesh() self.userMesh.loadFile("out.off") self.bbox = self.userMesh.getBBox() self.camera.centerOnBBox(self.bbox, theta = -math.pi/2, phi = math.pi/2) self.GUIState = STATE_SHOWPOINTS self.GUISubstate = SHOWPOINTS_ZOOMIN self.zoom = 0 self.setText = False self.repaint() def processEraseBackgroundEvent(self, event): pass #avoid flashing on MSW. def processSizeEvent(self, event): self.size = self.GetClientSize() self.SetCurrent(self.context) glViewport(0, 0, self.size.width, self.size.height) if not self.initiallyResized: #The canvas gets resized once on initialization so the camera needs #to be updated accordingly at that point self.camera = MousePolarCamera(self.size.width, self.size.height, ) self.camera.centerOnBBox(self.bbox, theta = -math.pi/2, phi = math.pi/2) self.initiallyResized = True def processPaintEvent(self, event): dc = wx.PaintDC(self) self.SetCurrent(self.context) if not self.GLinitialized: self.initGL() self.GLinitialized = True self.repaint() def handleIntroState(self): #Draw head glTranslatef(0, 0, self.zCenter) glRotatef(self.rotAngle, 0, 1, 0) glTranslatef(0, 0, -self.zCenter) self.headMesh.renderGL() self.rotAngle = self.rotAngle + 1 self.rotAngle = self.rotAngle % 360 #self.drawText(self.size[0]/2-50, self.size[1]-40, "A Head of Our Times") if not self.setText: self.titleText.SetLabelText("A Head of Our Times") self.startButton.SetLabelText("Click To Start") self.setText = True time.sleep(0.01) self.Refresh() def handleShowPointsState(self): if self.GUISubstate == SHOWPOINTS_ZOOMIN: if not self.setText: self.titleText.SetLabelText("Showing 3D Face Capture Result") glTranslatef(0, 0, self.zoom) self.userMesh.renderGL(drawEdges = 1, drawVerts = 1, drawNormals = 0, drawFaces = 0) glTranslatef(0, 0, -self.zoom) self.zoom = self.zoom + 0.005 time.sleep(0.01) if self.zoom >= abs(self.zCenter/6): self.GUISubstate = SHOWPOINTS_ROTATELEFT self.rotAngle = 0 self.rotCount = 0 elif self.GUISubstate == SHOWPOINTS_ROTATELEFT: self.setText = True glTranslatef(0, 0, self.zCenter + self.zoom) glRotatef(self.rotAngle, 0, 1, 0) glTranslatef(0, 0, -self.zCenter) if self.rotCount == 0: self.userMesh.renderGL(drawEdges = 1, drawVerts = 1, drawNormals = 0, drawFaces = 0) else: self.userMesh.renderGL(drawEdges = 0, drawVerts = 0, drawNormals = 0, drawFaces = 1, lightingOn = False) self.rotAngle = self.rotAngle - 1 if self.rotAngle < -60: self.GUISubstate = SHOWPOINTS_ROTATERIGHT time.sleep(0.01) elif self.GUISubstate == SHOWPOINTS_ROTATERIGHT: glTranslatef(0, 0, self.zCenter + self.zoom) glRotatef(self.rotAngle, 0, 1, 0) glTranslatef(0, 0, -self.zCenter) if self.rotCount == 0: self.userMesh.renderGL(drawEdges = 1, drawVerts = 1, drawNormals = 0, drawFaces = 0) else: self.userMesh.renderGL(drawEdges = 0, drawVerts = 0, drawNormals = 0, drawFaces = 1, lightingOn = False) self.rotAngle = self.rotAngle + 1 if self.rotAngle > 60: self.rotCount = self.rotCount + 1 if self.rotCount >= 2: self.GUISubstate = SHOWPOINTS_CENTER else: self.GUISubstate = SHOWPOINTS_ROTATELEFT time.sleep(0.01) elif self.GUISubstate == SHOWPOINTS_CENTER: glTranslatef(0, 0, self.zCenter + self.zoom) glRotatef(self.rotAngle, 0, 1, 0) glTranslatef(0, 0, -self.zCenter) self.userMesh.renderGL(drawEdges = 0, drawVerts = 0, drawNormals = 0, drawFaces = 1, lightingOn = False) self.rotAngle = self.rotAngle - 1 if self.rotAngle <= 0: self.GUISubstate = SHOWPOINTS_ZOOMOUT time.sleep(0.01) elif self.GUISubstate == SHOWPOINTS_ZOOMOUT: glTranslatef(0, 0, self.zoom) self.userMesh.renderGL(drawEdges = 0, drawVerts = 0, drawNormals = 0, drawFaces = 1, lightingOn = False) glTranslatef(0, 0, -self.zoom) self.zoom = self.zoom - 0.005 time.sleep(0.01) if self.zoom <= 0: self.GUIState = STATE_SHOWICP self.setText = False self.bbox = self.styrofoamHead.getBBox() self.camera.centerOnBBox(self.bbox, theta = -math.pi/2, phi = math.pi/2) #Get the mesh's renderbuffer ready before the thread starts so that no ICP frames are missed self.styrofoamHead.renderGL(drawEdges = 0, drawVerts = 0, drawNormals = 0, drawFaces = 1) self.ICPThread = ICPThread(self.userMesh, self.styrofoamHead, self, self.ICPMutex) self.ICPThread.start() self.drawText(self.size[0]/2-50, self.size[1]-40, "Showing Captured Face") self.Refresh() def transplantColors(self): perms = np.random.permutation(len(self.userMesh.vertices)) N = min(1000, len(perms)) VX = np.zeros((N, 3)) CX = np.zeros((N, 3)) #Randomly subsample points for speed for i in range(N): idx = perms[i] P = self.userMesh.vertices[idx].pos C = self.userMesh.vertices[idx].color VX[i, :] = np.array([P.x, P.y, P.z]) CX[i, :] = C VX = transformPoints(self.ICPTransformation, VX) self.titleText.SetLabelText("Placing Colors on Head") print "Getting initial guess of point positions..." ts, us = getInitialGuessClosestPoints(VX, self.styrofoamHead) print "Finished initial guess of point positions" self.colorUserMesh = transplantColorsLaplacianUsingBarycentric(self.styrofoamHead, CX, ts, us) def handleICPState(self): glPushMatrix() if self.ICPTransformation.shape[0] > 0: glMultMatrixd(self.ICPTransformation.transpose().flatten()) self.userMesh.renderGL(drawEdges = 0, drawVerts = 0, drawNormals = 0, drawFaces = 1, lightingOn = False) glPopMatrix() glColor3f(0.7, 0.7, 0.7) self.styrofoamHead.renderGL(drawEdges = 0, drawVerts = 0, drawNormals = 0, drawFaces = 1, lightingOn = True) #self.drawText(self.size[0]/2-50, self.size[1]-40, "Aligning Face with Statue...") if not self.setText: self.titleText.SetLabelText("Performing Rigid Alignment to Statue") self.setText = True if not self.ICPThread.isAlive(): print "Alignment finished" print "Transplanting colors..." self.transplantColors() print "Finished Transplanting colors" self.setText = False self.GUIState = STATE_DECAY self.timelineState = 0 self.bbox = self.colorUserMesh.getBBox() self.camera.centerOnBBox(self.bbox, theta = -math.pi/2, phi = math.pi/2) def handleDecayState(self): if self.timelineState > 40: #Render the head in its current form self.colorUserMesh.renderGL(drawEdges = 0, drawVerts = 0, drawNormals = 0, drawFaces = 1, lightingOn = True) if self.timelineState == 0: titleFont = wx.Font(24, wx.FONTFAMILY_DECORATIVE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD) self.titleText.SetFont(titleFont) if self.timelineState <= 20: #TODO: Include Images here self.titleText.SetLabelText("1180 - 1223: Paris becomes capital of French Kingdom") time.sleep(0.05) self.Refresh() elif self.timelineState <= 40: self.titleText.SetLabelText("1163: Construction of Notre Dame Cathedral Begins") time.sleep(0.05) self.Refresh() elif self.timelineState <= 60: self.titleText.SetLabelText("1245 - 1258: Remodling of North transept and addition of the Virtue") time.sleep(0.1) elif self.timelineState < 120: year = int(np.round((self.timelineState - 60)*(1793 - 1258)/60.0 + 1258)) self.titleText.SetLabelText("%i: Virtue in Situ on Cathedral Facade"%year) #Dampen the colors for v in self.colorUserMesh.vertices: C = v.color meanC = sum(C)/float(len(C)) v.color = [c - (c - meanC)*0.025 for c in C] self.colorUserMesh.needsDisplayUpdate = True else: if self.timelineState == 121: self.titleText.SetLabelText("1793: French Revolution and the Iconoclasm/Vandalism") #TODO: Rotate head slightly to left, fix chunks if self.timelineState == 120: USINGLAPLACIAN = False self.titleText.SetLabelText("1793: French Revolution Iconoclasm: Decapitation Imminent...") #Make some dents perms = np.random.permutation(len(self.colorUserMesh.vertices)) print "CHUNKING" constraints = [] chunks = 0 for i in range(0, 20): idx = perms[i] V = self.colorUserMesh.vertices[idx] if USINGLAPLACIAN: N = V.getNormal() #if np.abs(N.z) < 0.8: # continue chunks = chunks + 1 chunkSize = 0.05*np.random.rand(1)[0] P = V.pos - chunkSize*Vector3D(0, 0, -1) constraints.append((idx, P)) otherVerts = V.getVertexNeighbors() for V2 in otherVerts: P = V2.pos - chunkSize*0.5*Vector3D(0, 0, -1) constraints.append((V2.ID, P)) else: P = V.pos randDiff = 0.02*np.random.rand(1)[0] P = P - randDiff*V.getNormal() V.pos = P for V2 in V.getVertexNeighbors(): P = V2.pos - 0.5*randDiff*V2.getNormal() V2.pos = P if USINGLAPLACIAN: self.colorUserMesh.solveVertexPositionsWithConstraints(constraints) self.colorUserMesh.needsDisplayUpdate = True print "There were %i chunks"%chunks self.timelineState = self.timelineState + 1 self.Refresh() def handleShowStretchState(self): #TODO: Finish this self.GUIState = STATE_SHOWSTRETCH self.Refresh() def repaint(self): #Set up projection matrix glMatrixMode(GL_PROJECTION) glLoadIdentity() farDist = (self.camera.eye - self.bbox.getCenter()).Length()*2 #This is to make sure we can see on the inside farDist = max(farDist, self.bbox.getDiagLength()*2) nearDist = farDist/50.0 gluPerspective(180.0*self.camera.yfov/M_PI, float(self.size.x)/self.size.y, nearDist, farDist) #Set up modelview matrix self.camera.gotoCameraFrame() glClearColor(0.0, 0.0, 0.0, 0.0) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glLightfv(GL_LIGHT0, GL_POSITION, [3.0, 4.0, 5.0, 0.0]); glLightfv(GL_LIGHT1, GL_POSITION, [-3.0, -2.0, -3.0, 0.0]); glEnable(GL_LIGHTING) glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, [0.8, 0.8, 0.8, 1.0]); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, [0.2, 0.2, 0.2, 1.0]) glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, 64) self.zCenter = (self.bbox.zmax + self.bbox.zmin) / 2.0 if self.GUIState == STATE_INTRO: self.handleIntroState() elif self.GUIState == STATE_SHOWPOINTS: self.handleShowPointsState() elif self.GUIState == STATE_SHOWICP: self.handleICPState() elif self.GUIState == STATE_DECAY: self.handleDecayState() self.SwapBuffers() def initGL(self): glLightModelfv(GL_LIGHT_MODEL_AMBIENT, [0.2, 0.2, 0.2, 1.0]) glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE) glLightfv(GL_LIGHT0, GL_DIFFUSE, [1.0, 1.0, 1.0, 1.0]) glEnable(GL_LIGHT0) glLightfv(GL_LIGHT1, GL_DIFFUSE, [0.5, 0.5, 0.5, 1.0]) glEnable(GL_LIGHT1) glEnable(GL_NORMALIZE) glEnable(GL_LIGHTING) glEnable(GL_DEPTH_TEST) def handleMouseStuff(self, x, y): #Invert y from what the window manager says y = self.size.height - y self.MousePos = [x, y] def MouseDown(self, evt): x, y = evt.GetPosition() self.CaptureMouse() self.handleMouseStuff(x, y) self.Refresh() def MouseUp(self, evt): x, y = evt.GetPosition() self.handleMouseStuff(x, y) self.ReleaseMouse() self.Refresh() def MouseMotion(self, evt): x, y = evt.GetPosition() [lastX, lastY] = self.MousePos self.handleMouseStuff(x, y) dX = self.MousePos[0] - lastX dY = self.MousePos[1] - lastY if evt.Dragging(): if evt.MiddleIsDown(): self.camera.translate(dX, dY) elif evt.RightIsDown(): self.camera.zoom(-dY)#Want to zoom in as the mouse goes up elif evt.LeftIsDown(): self.camera.orbitLeftRight(dX) self.camera.orbitUpDown(dY) self.Refresh()
print "Updating %s to %g " % (v3.pos, v3.FMMDist) Q.put((v3.FMMDist, v3)) if e.f2: v3 = updateFMM(v1, v2, e.f2) if v3: print "Updating %s to %g " % (v3.pos, v3.FMMDist) Q.put((v3.FMMDist, v3)) v1.FMMType = FMM_BLACK_TYPE #Now copy over the distances to the matrix for k in range(0, N): D[i, k] = V[i].FMMDist return D if __name__ == '__main__': mesh = PolyMesh() v1 = mesh.addVertex(Point3D(0, 0, 0)) v2 = mesh.addVertex(Point3D(1, 0, 0)) v3 = mesh.addVertex(Point3D(1, 1, 0)) v4 = mesh.addVertex(Point3D(0, 1, 0)) v5 = mesh.addVertex(Point3D(1, 2, 0)) v6 = mesh.addVertex(Point3D(0, 2, 0)) mesh.addFace([v1, v2, v3]) mesh.addFace([v1, v3, v4]) mesh.addFace([v3, v5, v6]) mesh.addFace([v4, v3, v6]) mesh = getOctahedronMesh() getGeodesicDistancesFMM(mesh) mesh.saveOffFile("out.off")
plt.plot(angles[:, 1], 'r') plt.show() return angles if __name__ == '__main__': if len(sys.argv) < 4: print "Usage: python makeRotationImages.py <mesh name> <directory name> <NFrames>" sys.exit(0) [filename, dirName, NFrames] = [sys.argv[1], sys.argv[2], int(sys.argv[3])] np.random.seed(100) #For repeatable results randomly sampling if not os.path.exists(dirName): os.mkdir(dirName) m = PolyMesh() m.loadFile(filename) m.VPos = m.VPos * np.random.randn(m.VPos.shape[0], m.VPos.shape[1]) #Output rotation video #angles = 2*np.pi*np.random.rand(NFrames, 2) #angles = np.zeros((NFrames, 2)) #angles[:, 0] = np.linspace(0, 2*np.pi, NFrames+1)[0:NFrames] #angles = getUniformSphereAngles(3) [I, J] = np.meshgrid(np.linspace(0, 2 * np.pi, 30), np.linspace(0, 2 * np.pi, 30)) angles = np.zeros((I.size, 2)) angles[:, 0] = I.flatten()
class MeshViewerCanvas(glcanvas.GLCanvas): def __init__(self, parent): attribs = (glcanvas.WX_GL_RGBA, glcanvas.WX_GL_DOUBLEBUFFER, glcanvas.WX_GL_DEPTH_SIZE, 24) glcanvas.GLCanvas.__init__(self, parent, -1, attribList=attribs) self.context = glcanvas.GLContext(self) self.setText = False self.parent = parent #Camera state variables self.size = self.GetClientSize() #self.camera = MouseSphericalCamera(self.size.x, self.size.y) self.camera = MousePolarCamera(self.size.width, self.size.height) #Main state variables self.MousePos = [0, 0] self.initiallyResized = False random.seed() #GUI State Variables self.GUIState = STATE_INTRO self.GUISubstate = -1 #Head Mesh self.headMesh = PolyMesh() self.headMesh.loadFile('NotreDameMedium.off') self.headMeshLowres = PolyMesh() self.headMeshLowres.loadFile('NotreDameLowres.off') self.styrofoamHead = PolyMesh() self.styrofoamHead.loadFile('StyrofoamHead.off') self.rotAngle = 0 self.zoom = 0 self.rotCount = 0 self.timelineCount = 0 #User's face self.userMesh = None self.colorUserMesh = None #ICP state variables self.ICPTransformation = np.zeros(0) self.ICPMutex = Lock() self.ICPThread = None self.bbox = self.headMesh.getBBox() self.camera.centerOnBBox(self.bbox, theta=-math.pi / 2, phi=math.pi / 2) self.zCenter = (self.bbox.zmax + self.bbox.zmin) / 2.0 self.GLinitialized = False #GL-related events wx.EVT_ERASE_BACKGROUND(self, self.processEraseBackgroundEvent) wx.EVT_SIZE(self, self.processSizeEvent) wx.EVT_PAINT(self, self.processPaintEvent) #Mouse Events wx.EVT_LEFT_DOWN(self, self.MouseDown) wx.EVT_LEFT_UP(self, self.MouseUp) wx.EVT_RIGHT_DOWN(self, self.MouseDown) wx.EVT_RIGHT_UP(self, self.MouseUp) wx.EVT_MIDDLE_DOWN(self, self.MouseDown) wx.EVT_MIDDLE_UP(self, self.MouseUp) wx.EVT_MOTION(self, self.MouseMotion) self.initGL() def drawText(self, x, y, text, size=1, font=GLUT_BITMAP_TIMES_ROMAN_24): glDisable(GL_LIGHTING) glDisable(GL_DEPTH_TEST) glMatrixMode(GL_PROJECTION) glLoadIdentity() gluOrtho2D(0, self.size[0], 0, self.size[1]) glMatrixMode(GL_MODELVIEW) glLoadIdentity() glColor3f(1, 0, 0) glRasterPos2f(x, y) glPushMatrix() #for i in range(len(text)): # glutBitmapCharacter(font, ord(text[i])) glPopMatrix() glEnable(GL_LIGHTING) glEnable(GL_DEPTH_TEST) def startButtonHandler(self, evt): print "Starting Face capture..." if not self.setText: self.titleText.SetLabelText("Capturing Face...") self.setText = True #os.popen3("SingleFace.exe") #Captures the face process = subprocess.Popen("SingleFace", shell=True, stdout=subprocess.PIPE) process.wait() print "FINISHED CAPTURE" extractMeshFiles() #Convert the captured data to a triangulated mesh self.userMesh = LaplacianMesh() self.userMesh.loadFile("out.off") self.bbox = self.userMesh.getBBox() self.camera.centerOnBBox(self.bbox, theta=-math.pi / 2, phi=math.pi / 2) self.GUIState = STATE_SHOWPOINTS self.GUISubstate = SHOWPOINTS_ZOOMIN self.zoom = 0 self.setText = False self.repaint() def processEraseBackgroundEvent(self, event): pass #avoid flashing on MSW. def processSizeEvent(self, event): self.size = self.GetClientSize() self.SetCurrent(self.context) glViewport(0, 0, self.size.width, self.size.height) if not self.initiallyResized: #The canvas gets resized once on initialization so the camera needs #to be updated accordingly at that point self.camera = MousePolarCamera( self.size.width, self.size.height, ) self.camera.centerOnBBox(self.bbox, theta=-math.pi / 2, phi=math.pi / 2) self.initiallyResized = True def processPaintEvent(self, event): dc = wx.PaintDC(self) self.SetCurrent(self.context) if not self.GLinitialized: self.initGL() self.GLinitialized = True self.repaint() def handleIntroState(self): #Draw head glTranslatef(0, 0, self.zCenter) glRotatef(self.rotAngle, 0, 1, 0) glTranslatef(0, 0, -self.zCenter) self.headMesh.renderGL() self.rotAngle = self.rotAngle + 1 self.rotAngle = self.rotAngle % 360 #self.drawText(self.size[0]/2-50, self.size[1]-40, "A Head of Our Times") if not self.setText: self.titleText.SetLabelText("A Head of Our Times") self.startButton.SetLabelText("Click To Start") self.setText = True time.sleep(0.01) self.Refresh() def handleShowPointsState(self): if self.GUISubstate == SHOWPOINTS_ZOOMIN: if not self.setText: self.titleText.SetLabelText("Showing 3D Face Capture Result") glTranslatef(0, 0, self.zoom) self.userMesh.renderGL(drawEdges=1, drawVerts=1, drawNormals=0, drawFaces=0) glTranslatef(0, 0, -self.zoom) self.zoom = self.zoom + 0.005 time.sleep(0.01) if self.zoom >= abs(self.zCenter / 6): self.GUISubstate = SHOWPOINTS_ROTATELEFT self.rotAngle = 0 self.rotCount = 0 elif self.GUISubstate == SHOWPOINTS_ROTATELEFT: self.setText = True glTranslatef(0, 0, self.zCenter + self.zoom) glRotatef(self.rotAngle, 0, 1, 0) glTranslatef(0, 0, -self.zCenter) if self.rotCount == 0: self.userMesh.renderGL(drawEdges=1, drawVerts=1, drawNormals=0, drawFaces=0) else: self.userMesh.renderGL(drawEdges=0, drawVerts=0, drawNormals=0, drawFaces=1, lightingOn=False) self.rotAngle = self.rotAngle - 1 if self.rotAngle < -60: self.GUISubstate = SHOWPOINTS_ROTATERIGHT time.sleep(0.01) elif self.GUISubstate == SHOWPOINTS_ROTATERIGHT: glTranslatef(0, 0, self.zCenter + self.zoom) glRotatef(self.rotAngle, 0, 1, 0) glTranslatef(0, 0, -self.zCenter) if self.rotCount == 0: self.userMesh.renderGL(drawEdges=1, drawVerts=1, drawNormals=0, drawFaces=0) else: self.userMesh.renderGL(drawEdges=0, drawVerts=0, drawNormals=0, drawFaces=1, lightingOn=False) self.rotAngle = self.rotAngle + 1 if self.rotAngle > 60: self.rotCount = self.rotCount + 1 if self.rotCount >= 2: self.GUISubstate = SHOWPOINTS_CENTER else: self.GUISubstate = SHOWPOINTS_ROTATELEFT time.sleep(0.01) elif self.GUISubstate == SHOWPOINTS_CENTER: glTranslatef(0, 0, self.zCenter + self.zoom) glRotatef(self.rotAngle, 0, 1, 0) glTranslatef(0, 0, -self.zCenter) self.userMesh.renderGL(drawEdges=0, drawVerts=0, drawNormals=0, drawFaces=1, lightingOn=False) self.rotAngle = self.rotAngle - 1 if self.rotAngle <= 0: self.GUISubstate = SHOWPOINTS_ZOOMOUT time.sleep(0.01) elif self.GUISubstate == SHOWPOINTS_ZOOMOUT: glTranslatef(0, 0, self.zoom) self.userMesh.renderGL(drawEdges=0, drawVerts=0, drawNormals=0, drawFaces=1, lightingOn=False) glTranslatef(0, 0, -self.zoom) self.zoom = self.zoom - 0.005 time.sleep(0.01) if self.zoom <= 0: self.GUIState = STATE_SHOWICP self.setText = False self.bbox = self.styrofoamHead.getBBox() self.camera.centerOnBBox(self.bbox, theta=-math.pi / 2, phi=math.pi / 2) #Get the mesh's renderbuffer ready before the thread starts so that no ICP frames are missed self.styrofoamHead.renderGL(drawEdges=0, drawVerts=0, drawNormals=0, drawFaces=1) self.ICPThread = ICPThread(self.userMesh, self.styrofoamHead, self, self.ICPMutex) self.ICPThread.start() self.drawText(self.size[0] / 2 - 50, self.size[1] - 40, "Showing Captured Face") self.Refresh() def transplantColors(self): perms = np.random.permutation(len(self.userMesh.vertices)) N = min(1000, len(perms)) VX = np.zeros((N, 3)) CX = np.zeros((N, 3)) #Randomly subsample points for speed for i in range(N): idx = perms[i] P = self.userMesh.vertices[idx].pos C = self.userMesh.vertices[idx].color VX[i, :] = np.array([P.x, P.y, P.z]) CX[i, :] = C VX = transformPoints(self.ICPTransformation, VX) self.titleText.SetLabelText("Placing Colors on Head") print "Getting initial guess of point positions..." ts, us = getInitialGuessClosestPoints(VX, self.styrofoamHead) print "Finished initial guess of point positions" self.colorUserMesh = transplantColorsLaplacianUsingBarycentric( self.styrofoamHead, CX, ts, us) def handleICPState(self): glPushMatrix() if self.ICPTransformation.shape[0] > 0: glMultMatrixd(self.ICPTransformation.transpose().flatten()) self.userMesh.renderGL(drawEdges=0, drawVerts=0, drawNormals=0, drawFaces=1, lightingOn=False) glPopMatrix() glColor3f(0.7, 0.7, 0.7) self.styrofoamHead.renderGL(drawEdges=0, drawVerts=0, drawNormals=0, drawFaces=1, lightingOn=True) #self.drawText(self.size[0]/2-50, self.size[1]-40, "Aligning Face with Statue...") if not self.setText: self.titleText.SetLabelText("Performing Rigid Alignment to Statue") self.setText = True if not self.ICPThread.isAlive(): print "Alignment finished" print "Transplanting colors..." self.transplantColors() print "Finished Transplanting colors" self.setText = False self.GUIState = STATE_DECAY self.timelineState = 0 self.bbox = self.colorUserMesh.getBBox() self.camera.centerOnBBox(self.bbox, theta=-math.pi / 2, phi=math.pi / 2) def handleDecayState(self): if self.timelineState > 40: #Render the head in its current form self.colorUserMesh.renderGL(drawEdges=0, drawVerts=0, drawNormals=0, drawFaces=1, lightingOn=True) if self.timelineState == 0: titleFont = wx.Font(24, wx.FONTFAMILY_DECORATIVE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD) self.titleText.SetFont(titleFont) if self.timelineState <= 20: #TODO: Include Images here self.titleText.SetLabelText( "1180 - 1223: Paris becomes capital of French Kingdom") time.sleep(0.05) self.Refresh() elif self.timelineState <= 40: self.titleText.SetLabelText( "1163: Construction of Notre Dame Cathedral Begins") time.sleep(0.05) self.Refresh() elif self.timelineState <= 60: self.titleText.SetLabelText( "1245 - 1258: Remodling of North transept and addition of the Virtue" ) time.sleep(0.1) elif self.timelineState < 120: year = int( np.round((self.timelineState - 60) * (1793 - 1258) / 60.0 + 1258)) self.titleText.SetLabelText( "%i: Virtue in Situ on Cathedral Facade" % year) #Dampen the colors for v in self.colorUserMesh.vertices: C = v.color meanC = sum(C) / float(len(C)) v.color = [c - (c - meanC) * 0.025 for c in C] self.colorUserMesh.needsDisplayUpdate = True else: if self.timelineState == 121: self.titleText.SetLabelText( "1793: French Revolution and the Iconoclasm/Vandalism") #TODO: Rotate head slightly to left, fix chunks if self.timelineState == 120: USINGLAPLACIAN = False self.titleText.SetLabelText( "1793: French Revolution Iconoclasm: Decapitation Imminent..." ) #Make some dents perms = np.random.permutation(len(self.colorUserMesh.vertices)) print "CHUNKING" constraints = [] chunks = 0 for i in range(0, 20): idx = perms[i] V = self.colorUserMesh.vertices[idx] if USINGLAPLACIAN: N = V.getNormal() #if np.abs(N.z) < 0.8: # continue chunks = chunks + 1 chunkSize = 0.05 * np.random.rand(1)[0] P = V.pos - chunkSize * Vector3D(0, 0, -1) constraints.append((idx, P)) otherVerts = V.getVertexNeighbors() for V2 in otherVerts: P = V2.pos - chunkSize * 0.5 * Vector3D(0, 0, -1) constraints.append((V2.ID, P)) else: P = V.pos randDiff = 0.02 * np.random.rand(1)[0] P = P - randDiff * V.getNormal() V.pos = P for V2 in V.getVertexNeighbors(): P = V2.pos - 0.5 * randDiff * V2.getNormal() V2.pos = P if USINGLAPLACIAN: self.colorUserMesh.solveVertexPositionsWithConstraints( constraints) self.colorUserMesh.needsDisplayUpdate = True print "There were %i chunks" % chunks self.timelineState = self.timelineState + 1 self.Refresh() def handleShowStretchState(self): #TODO: Finish this self.GUIState = STATE_SHOWSTRETCH self.Refresh() def repaint(self): #Set up projection matrix glMatrixMode(GL_PROJECTION) glLoadIdentity() farDist = (self.camera.eye - self.bbox.getCenter()).Length() * 2 #This is to make sure we can see on the inside farDist = max(farDist, self.bbox.getDiagLength() * 2) nearDist = farDist / 50.0 gluPerspective(180.0 * self.camera.yfov / M_PI, float(self.size.x) / self.size.y, nearDist, farDist) #Set up modelview matrix self.camera.gotoCameraFrame() glClearColor(0.0, 0.0, 0.0, 0.0) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glLightfv(GL_LIGHT0, GL_POSITION, [3.0, 4.0, 5.0, 0.0]) glLightfv(GL_LIGHT1, GL_POSITION, [-3.0, -2.0, -3.0, 0.0]) glEnable(GL_LIGHTING) glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, [0.8, 0.8, 0.8, 1.0]) glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, [0.2, 0.2, 0.2, 1.0]) glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, 64) self.zCenter = (self.bbox.zmax + self.bbox.zmin) / 2.0 if self.GUIState == STATE_INTRO: self.handleIntroState() elif self.GUIState == STATE_SHOWPOINTS: self.handleShowPointsState() elif self.GUIState == STATE_SHOWICP: self.handleICPState() elif self.GUIState == STATE_DECAY: self.handleDecayState() self.SwapBuffers() def initGL(self): glLightModelfv(GL_LIGHT_MODEL_AMBIENT, [0.2, 0.2, 0.2, 1.0]) glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE) glLightfv(GL_LIGHT0, GL_DIFFUSE, [1.0, 1.0, 1.0, 1.0]) glEnable(GL_LIGHT0) glLightfv(GL_LIGHT1, GL_DIFFUSE, [0.5, 0.5, 0.5, 1.0]) glEnable(GL_LIGHT1) glEnable(GL_NORMALIZE) glEnable(GL_LIGHTING) glEnable(GL_DEPTH_TEST) def handleMouseStuff(self, x, y): #Invert y from what the window manager says y = self.size.height - y self.MousePos = [x, y] def MouseDown(self, evt): x, y = evt.GetPosition() self.CaptureMouse() self.handleMouseStuff(x, y) self.Refresh() def MouseUp(self, evt): x, y = evt.GetPosition() self.handleMouseStuff(x, y) self.ReleaseMouse() self.Refresh() def MouseMotion(self, evt): x, y = evt.GetPosition() [lastX, lastY] = self.MousePos self.handleMouseStuff(x, y) dX = self.MousePos[0] - lastX dY = self.MousePos[1] - lastY if evt.Dragging(): if evt.MiddleIsDown(): self.camera.translate(dX, dY) elif evt.RightIsDown(): self.camera.zoom(-dY) #Want to zoom in as the mouse goes up elif evt.LeftIsDown(): self.camera.orbitLeftRight(dX) self.camera.orbitUpDown(dY) self.Refresh()
#solver: Eigen simplicialLLT solver that has Laplace Beltrami + anchors #deltaCoords: numpy array of delta coordinates #anchors: numpy array of anchor positions #anchorWeights: weight of anchors def solveLaplacianMatrixIGLSoft(solver, L, M_inv, deltaCoords, anchorsIdx, anchors, anchorWeights): print "solveLaplacianMatrixIGLSoft: anchorWeights = %g"%anchorWeights y = np.array(L*M_inv*igl.eigen.MatrixXd(np.array(deltaCoords, dtype=np.float64))) y[anchorsIdx] += anchorWeights*anchors y = igl.eigen.MatrixXd(y) ret = solver.solve(y) return np.array(ret) if __name__ == '__main__2': anchorWeights = 10000 m = PolyMesh() m.loadOffFile("cow.off") m.performDisplayUpdate() X = sio.loadmat("anchors.mat") anchors = X['anchors'] anchorsIdx = X['anchorsIdx'].flatten().tolist() deltaCoords = X['deltaCoords'] L = makeLaplacianMatrixCotWeights(m.VPos, m.ITris, anchorsIdx, anchorWeights) m.VPos = solveLaplacianMatrix(L, deltaCoords, anchors, anchorWeights) m.saveOffFile("LapCow.off") if __name__ == '__main__3': anchorWeights = 100 m = getSphereMesh(1, 2) print "BBox Before: ", m.getBBox() m.performDisplayUpdate()
import ShapeStatistics as shp NUM_PER_CLASS = 10 POINTCLOUD_CLASSES = ['biplane', 'desk_chair', 'dining_chair', 'fighter_jet', 'fish', 'flying_bird', 'guitar', 'handgun', 'head', 'helicopter', 'human', 'human_arms_out', 'potted_plant', 'race_car', 'sedan', 'shelves', 'ship', 'sword', 'table', 'vase'] NRandSamples = 10000 #You can tweak this number np.random.seed(100) #For repeatable results randomly sampling #Load in and sample all meshes PointClouds = [] Normals = [] for i in range(len(POINTCLOUD_CLASSES)): print "LOADING CLASS %i of %i..."%(i, len(POINTCLOUD_CLASSES)) PCClass = [] for j in range(NUM_PER_CLASS): m = PolyMesh() filename = "models_off/%s%i.off"%(POINTCLOUD_CLASSES[i], j) print "Loading ", filename m.loadOffFileExternal(filename) (Ps, Ns) = shp.samplePointCloud(m, NRandSamples) PointClouds.append(Ps) Normals.append(Ns) # Precision recall for all classes of shapes, averaged together SPoints = shp.getSphereSamples(2) H0 = shp.makeAllHistograms(PointClouds, Normals, shp.getShapeHistogram, 5, 3.0) H1 = shp.makeAllHistograms(PointClouds, Normals, shp.getShapeHistogram, 10, 3.0) H2 = shp.makeAllHistograms(PointClouds, Normals, shp.getShapeHistogram, 30, 3.0)
plt.plot(angles[:, 1], "r") plt.show() return angles if __name__ == "__main__": if len(sys.argv) < 4: print "Usage: python makeRotationImages.py <mesh name> <directory name> <NFrames>" sys.exit(0) [filename, dirName, NFrames] = [sys.argv[1], sys.argv[2], int(sys.argv[3])] np.random.seed(100) # For repeatable results randomly sampling if not os.path.exists(dirName): os.mkdir(dirName) m = PolyMesh() m.loadFile(filename) m.VPos = m.VPos * np.random.randn(m.VPos.shape[0], m.VPos.shape[1]) # Output rotation video # angles = 2*np.pi*np.random.rand(NFrames, 2) # angles = np.zeros((NFrames, 2)) # angles[:, 0] = np.linspace(0, 2*np.pi, NFrames+1)[0:NFrames] # angles = getUniformSphereAngles(3) [I, J] = np.meshgrid(np.linspace(0, 2 * np.pi, 30), np.linspace(0, 2 * np.pi, 30)) angles = np.zeros((I.size, 2)) angles[:, 0] = I.flatten() angles[:, 1] = J.flatten()
# Adapted from Chris Tralie's manipulateGeometry.py import sys sys.path.append("S3DGLPy") from PolyMesh import * import numpy as np if __name__ == '__main__': if len(sys.argv) < 2: sys.exit(1) meshin = sys.argv[1] meshout = sys.argv[2] m = PolyMesh() (VPos, VColors, ITris) = loadOffFileExternal(meshin) #Note: Points come into the program as a matrix in rows, so we need #to transpose to get them into our column format VPos = VPos.T #Make a random rotation matrix R = np.eye(3, 3) R[2, 2] = -1 print(R) #Apply rotation VPos = R.dot(VPos) #Save the results VPos = VPos.T #Need to transpose back before saving saveOffFileExternal(meshout, VPos, VColors * 255, ITris)
break rIn += 1 #increment row counter i.e. move to next row PR = PR / len( D ) #divide all precision values by number of rows i.e find average as summation of precision values/number of precision values return PR ######################################################### ## MAIN TESTS ## ######################################################### #sys.exit("Not executing rest of code") if __name__ == '__main__': m = PolyMesh() m.loadFile("models_off/biplane0.off") #Load a mesh (Ps, Ns) = samplePointCloud(m, 5) #Sample 20,000 points and associated normals exportPointCloud(Ps, Ns, "biplane.pts") #Export point cloud #TESTING GET-SHAPE-HISTOGRAM #histogram1 = getShapeHistogram(Ps, Ns, 21, 3) #print histogram1 #print bins1 #plt.bar(bins1, histogram1, width=3.0/21*0.9) #plt.show() #TESTING GET-2D-HISTOGRAM #DMax = 4 #NBins = 20