patternpythonMinor
Applying Laplacian smoothing to vertices in a mesh
Viewed 0 times
meshlaplaciansmoothingapplyingvertices
Problem
I'm totally new in Python and I wrote some code. It is a simple algorithm to smooth objects. I need to find adjacent vertices in mesh and sum their coordinates and after that divide by a number of adjacent vertices. This algorithm is called Laplacian Smoothing.
Could anybody point out how to make it better?
Could anybody point out how to make it better?
n = mesh.VPos.shape[0]
final = []
for i in range(n):
neighbors = mesh.vertices[i].getVertexNeighbors()
indices = map(lambda x: x.ID, neighbors)
z = len(indices)
help = []
for j in indices:
help.append([mesh.VPos[j]])
final += [sum(x)/z for x in zip(*help)]
final = np.array(final)
mesh.VPos = finalSolution
The code is not that bad at all.
Here are a few notes:
indices = [x.ID for x in neighbors]
-
indices = map(lambda x: x.ID, neighbors)
z = len(indices)
help = []
for j in indices:
help.append([mesh.VPos[j]])
final += [sum(x)/z for x in zip(*help)]
you can simply do this
help = ([mesh.VPos[j.ID]] for j in neighbors)
z = len(neighbors)
final.extend(sum(x)/z for x in zip(*help))
mesh.VPos = np.array(final)
for j in indices:
help.append(mesh.VPos[j])
final += [sum(help) / z]
So after the edits it'll look something like this
Alternatively you can use
Note that you cannot give a generator argument to
Here are a few notes:
- Use list comprehension – it's more readable than maps & lambdas
indices = [x.ID for x in neighbors]
-
indices isn't really necessary. Instead ofindices = map(lambda x: x.ID, neighbors)
z = len(indices)
help = []
for j in indices:
help.append([mesh.VPos[j]])
final += [sum(x)/z for x in zip(*help)]
you can simply do this
help = ([mesh.VPos[j.ID]] for j in neighbors)
z = len(neighbors)
final.extend(sum(x)/z for x in zip(*help))
help is a generator expression here, since you don't really need a list. That will probably save some overhead of creating the list. You can also avoid creating a new list of sum(x)/z and directly append all values to final using the extend method.- Instead of reassigning a numpy array to
final, I'd just do
mesh.VPos = np.array(final)
- I'm not completely sure, but I think the inner lists
[mesh.VPos[j]]combined withzip(*help)will amount to the same as just
for j in indices:
help.append(mesh.VPos[j])
final += [sum(help) / z]
- You can create a
numpy.ndarrayright at the beginning instead of using a Pythonlistand then converting it.
So after the edits it'll look something like this
n = mesh.VPos.shape[0]
final = np.empty(n) # change dtype if you need to
for i in range(n):
neighbors = mesh.vertices[i].getVertexNeighbors()
help = (mesh.VPos[j.ID] for j in neighbors)
final[i] = sum(help) / len(neighbors)
mesh.VPos = finalAlternatively you can use
numpy.mean to compute sum(help) / len(neighbors):n = mesh.VPos.shape[0]
final = np.empty(n) # change dtype if you need to
for i in range(n):
neighbors = mesh.vertices[i].getVertexNeighbors()
help = [mesh.VPos[j.ID] for j in neighbors]
final[i] = np.mean(help)
mesh.VPos = finalNote that you cannot give a generator argument to
numpy.mean, it has to be a list (or anything with __len__ method).Code Snippets
n = mesh.VPos.shape[0]
final = np.empty(n) # change dtype if you need to
for i in range(n):
neighbors = mesh.vertices[i].getVertexNeighbors()
help = (mesh.VPos[j.ID] for j in neighbors)
final[i] = sum(help) / len(neighbors)
mesh.VPos = finaln = mesh.VPos.shape[0]
final = np.empty(n) # change dtype if you need to
for i in range(n):
neighbors = mesh.vertices[i].getVertexNeighbors()
help = [mesh.VPos[j.ID] for j in neighbors]
final[i] = np.mean(help)
mesh.VPos = finalContext
StackExchange Code Review Q#159621, answer score: 3
Revisions (0)
No revisions yet.