-
Notifications
You must be signed in to change notification settings - Fork 25
Examples
Much of the homework in this class will consist of filling out skeleton methods; these examples are individual methods rather than complete programs.
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 longestLenWrite 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 maxMeanDegreeWrite 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 vectorMeanConsider 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 maxProjectedLengthEdgeNote 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.
These methods are complete programs, although they exclude the repetitive importing code at the beginning of each program.
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()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()