Skip to content

Examples

Nick Sharp edited this page Jan 26, 2016 · 2 revisions

Skeleton Function Examples

Much of the homework in this class will consist of filling out skeleton methods; these examples are individual methods rather than complete programs.

Basic iterators 1

Write a function which returns the length of the longest edge adjacent to a vertex

def longestEdge(self):

    longestLen = -1
    for halfedge in self.adjacentHalfEdges():
        if norm(halfedge.vector) > longestLen:    # this is one way of finding a max
            longestLen = norm(halfedge.vector)

    return longestLen

Basic iterators 2

Write a function which, at a face, will output the average degree of the vertices that neighbor that face. Also write a function which will return the largest value of this quantity for any face in the mesh.

def meanDegree(self):
    degreeSum = 0.0
    n = 0.0
    for vert in self.adjacentVerts():
        degreeSum += vert.degree
        n += 1.0
    degreeMean = degreeSum / n
    return degreeMean

def maxMeanDegree():
    maxMeanDegree = -1.0
    for f in mesh.faces:
        maxMeanDegree = max((maxMeanDegree, f.meanDegree)) # alternate way of taking a max
    return maxMeanDegree

Basic iterators 3 and vector arithmetic

Write a function which will, at a vertex, compute the mean vector over all outgoing edges

def meanDirection(self):
    vectorSum = Vector3D(0.0, 0.0, 0.0)
    n = 0.0
    for halfedge in self.adjacentHalfEdges():
        vectorSum += halfedge.vector
        n += 1.0
    vectorMean = vectorSum / n
    return vectorMean

Projection and modular indexing

Consider the edges which emanate from a vertex, indexed in counter-clockwise order as e_i. For each e_i, we can compute the length of e_i when projected on to e_(i+1). Write a function which returns the edge with the greatest value of this length, at a given vertex.

def maxProjectedEdge(self):

    # Get a list of halfedges that emanate from this vertex. Since we need
    # to process consecutive halfedges, we can't just handle them one at a
    # time from an iterator.
    halfEdgeList = list(self.adjacentHalfEdges())

    # These values will store the current max and the edge which attained
    # that max
    maxProjectedLength = 0.0
    maxProjectedLengthEdge = None

    # Use modular indexing to process the consecutive values
    for i in range(len(halfEdgeList)):

        # These are the two halfedge objects under consideration
        a = halfEdgeList[i]
        b = halfEdgeList[(i+1)%len(halfEdgeList)]

        # Compute the length
        projectedLength = dot(normalize(a.vector), b.vector)

        # Check if this is the new max
        if projectedLength > maxProjectedLength:
            maxProjectedLength = projectedLength
            maxProjectedLengthEdge = b.edge

    return maxProjectedLengthEdge

Note that in this example, the roles of halfedges a and b are the opposite of what might be expected. This is because the twin.next process used to iterate around the edges in Vertex.adjacentHalfEdges() yields a clockwise traversal, but the question asks for counter-clockwise pairs.

Complete Program Examples

These methods are complete programs, although they exclude the repetitive importing code at the beginning of each program.

Computing with vector data

This program reads a mesh, computes a new vector at each vertex (which happens to be the cross-product of the normal with the vector (1,1,1), and displays the result.

def main():

    # Get the path for the mesh to load, either from the program argument if
    # one was given, or a dialog otherwise
    if(len(sys.argv) > 1):
        filename = sys.argv[1]
    else:
        print("ERROR: No file name specified. Proper syntax is 'python program.py path/to/your/mesh.obj'.")
        exit()

    # Read in the mesh
    mesh = HalfEdgeMesh(readMesh(filename))

    # Create a viewer object
    winName = 'DDG Test -- ' + os.path.basename(filename)
    meshDisplay = MeshDisplay(windowTitle=winName)
    meshDisplay.setMesh(mesh)

    # Compute a vector at each vertex which is the cross product of the normal
    # and (1,1,1)
    directionVector = Vector3D(1.0,1.0,1.0)
    @property
    @cacheGeometry
    def myVector(self):
        return cross(self.normal, directionVector)
    Vertex.myVector = myVector

    # Visualize this newly computed vector
    meshDisplay.setVectors('myVector')

    # Start the viewer running
    meshDisplay.startMainLoop()


if __name__ == "__main__": main()

Scalar quantities on faces

This program reads a mesh, computes the average vertex degree at each face, and displays the result.

def main():

    # Get the path for the mesh to load, either from the program argument if
    # one was given, or a dialog otherwise
    if(len(sys.argv) > 1):
        filename = sys.argv[1]
    else:
        print("ERROR: No file name specified. Proper syntax is 'python program.py path/to/your/mesh.obj'.")
        exit()

    # Read in the mesh
    mesh = HalfEdgeMesh(readMesh(filename))

    # Create a viewer object
    winName = 'DDG Test -- ' + os.path.basename(filename)
    meshDisplay = MeshDisplay(windowTitle=winName)
    meshDisplay.setMesh(mesh)

    # Compute the mean degree at a face
    directionVector = Vector3D(1.0,1.0,1.0)
    @property
    @cacheGeometry
    def meanDegree(self):
        degreeSum = 0.0
        n = 0.0
        for vert in self.adjacentVerts():
            degreeSum += vert.degree
            n += 1.0
        degreeMean = degreeSum / n
        return degreeMean

    Face.meanDegree = meanDegree

    # Visualize this newly computed scalar value
    meshDisplay.setShapeColorFromScalar('meanDegree', definedOn='face')

    # Start the viewer running
    meshDisplay.startMainLoop()


if __name__ == "__main__": main()

Clone this wiki locally