-
-
Notifications
You must be signed in to change notification settings - Fork 35
/
mesh.py
87 lines (72 loc) · 2.92 KB
/
mesh.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# -----------------------------------------------------------------------------
# Copyright (c) 2020 Nicolas P. Rougier. All rights reserved.
# Distributed under the (new) BSD License.
# -----------------------------------------------------------------------------
import numpy as np
import mpl3d.glm as glm
import matplotlib as mpl
from matplotlib.collections import PolyCollection
class Mesh():
"""
Mesh described by vertices and faces
"""
def __init__(self, ax, transform, vertices, faces,
cmap=None, facecolors="white", edgecolors="black",
linewidths=0.5, mode="front"):
"""
"""
self.collection = PolyCollection([], clip_on=False, snap=False)
self.vertices = vertices
self.faces = faces
self.cmap = cmap
self.facecolors = mpl.colors.to_rgba_array(facecolors)
self.edgecolors = mpl.colors.to_rgba_array(edgecolors)
self.linewidths = linewidths
self.mode = mode
self.update(transform)
ax.add_collection(self.collection, autolim=False)
def update(self, transform):
"""
Update mesh according to transform (4x4 array)
"""
T = glm.transform(self.vertices, transform)[self.faces]
Z = -T[:,:,2].mean(axis=1)
if self.cmap is not None:
# Facecolors using depth buffer
norm = mpl.colors.Normalize(vmin=Z.min(),vmax=Z.max())
facecolors = self.cmap(norm(Z))
else:
facecolors = self.facecolors
edgecolors = self.edgecolors
linewidths = self.linewidths
# Back face culling
if self.mode == "front":
front, back = glm.frontback(T)
T, Z = T[front], Z[front]
if len(facecolors) == len(self.faces):
facecolors = facecolors[front]
if len(edgecolors) == len(self.faces):
edgecolors = edgecolors[front]
# Front face culling
elif self.mode == "back":
front, back = glm.frontback(T)
T, Z = T[back], Z[back]
if len(facecolors) == len(self.faces):
facecolors = facecolors[back]
if len(edgecolor) == len(self.faces):
edgecolors = edgecolors[back]
# Separate 2d triangles from zbuffer
triangles = T[:,:,:2]
antialiased = linewidths > 0
# Sort triangles according to z buffer
I = np.argsort(Z)
triangles = triangles[I,:]
if len(facecolors) == len(I):
facecolors = facecolors[I,:]
if len(edgecolors) == len(I):
edgecolors = edgecolors[I,:]
self.collection.set_verts(triangles)
self.collection.set_linewidths(linewidths)
self.collection.set_facecolors(facecolors)
self.collection.set_edgecolors(edgecolors)
self.collection.set_antialiased(antialiased)