meshplot
meshplot copied to clipboard
Adding transparency/opacity/alpha
Hi meshplot, Have really benefited a lot from this library so thank you. I'd like to visualise a mesh that is partially transparent. Is this option available already?
Happy to contribute something but I'm not sure where to start - at a complete guess I figure https://github.com/skoch9/meshplot/blob/d780cc5db68d545fb68e1f81176ce63818712682/meshplot/Viewer.py#L230 which (I think) instantiates the mesh from pythreejs. Looks like the pythreejs MeshStandardMaterial
does have an option alphaMap
to handle transparency.
Thanks! Lewis
Something like this was working for me
def add_transparent_mesh(self, v, f, c=None, uv=None, n=None, shading={}, opacity=0.6):
import pythreejs as p3s
sh = self._Viewer__get_shading(shading)
mesh_obj = {}
#it is a tet
if v.shape[1] == 3 and f.shape[1] == 4:
f_tmp = np.ndarray([f.shape[0]*4, 3], dtype=f.dtype)
for i in range(f.shape[0]):
f_tmp[i*4+0] = np.array([f[i][1], f[i][0], f[i][2]])
f_tmp[i*4+1] = np.array([f[i][0], f[i][1], f[i][3]])
f_tmp[i*4+2] = np.array([f[i][1], f[i][2], f[i][3]])
f_tmp[i*4+3] = np.array([f[i][2], f[i][0], f[i][3]])
f = f_tmp
if v.shape[1] == 2:
v = np.append(v, np.zeros([v.shape[0], 1]), 1)
# Type adjustment vertices
v = v.astype("float32", copy=False)
# Color setup
colors, coloring = self._Viewer__get_colors(v, f, c, sh)
# Type adjustment faces and colors
c = colors.astype("float32", copy=False)
# Material and geometry setup
ba_dict = {"color": p3s.BufferAttribute(c)}
if coloring == "FaceColors":
verts = np.zeros((f.shape[0]*3, 3), dtype="float32")
for ii in range(f.shape[0]):
#print(ii*3, f[ii])
verts[ii*3] = v[f[ii,0]]
verts[ii*3+1] = v[f[ii,1]]
verts[ii*3+2] = v[f[ii,2]]
v = verts
else:
f = f.astype("uint32", copy=False).ravel()
ba_dict["index"] = p3s.BufferAttribute(f, normalized=False)
ba_dict["position"] = p3s.BufferAttribute(v, normalized=False)
if uv is not None:
uv = (uv - np.min(uv)) / (np.max(uv) - np.min(uv))
# tex = p3s.DataTexture(data=texture_data, format="RGBFormat", type="FloatType")
material = p3s.MeshStandardMaterial(map=texture_data, reflectivity=sh["reflectivity"], side=sh["side"],
roughness=sh["roughness"], metalness=sh["metalness"], flatShading=sh["flat"],
polygonOffset=True, polygonOffsetFactor= 1, polygonOffsetUnits=5)
ba_dict["uv"] = p3s.BufferAttribute(uv.astype("float32", copy=False))
else:
material = p3s.MeshStandardMaterial(vertexColors=coloring, reflectivity=sh["reflectivity"],
side=sh["side"], roughness=sh["roughness"], metalness=sh["metalness"],
opacity=opacity, transparent=True,alphaTest=opacity*0.99,
blending='CustomBlending',depthWrite=False,
flatShading=True)
if type(n) != type(None) and coloring == "VertexColors":
ba_dict["normal"] = p3s.BufferAttribute(n.astype("float32", copy=False), normalized=True)
geometry = p3s.BufferGeometry(attributes=ba_dict)
if coloring == "VertexColors" and type(n) == type(None):
geometry.exec_three_obj_method('computeVertexNormals')
elif coloring == "FaceColors" and type(n) == type(None):
geometry.exec_three_obj_method('computeFaceNormals')
# Mesh setup
mesh = p3s.Mesh(geometry=geometry, material=material)
# Wireframe setup
mesh_obj["wireframe"] = None
# Object setup
mesh_obj["max"] = np.max(v, axis=0)
mesh_obj["min"] = np.min(v, axis=0)
mesh_obj["geometry"] = geometry
mesh_obj["mesh"] = mesh
mesh_obj["material"] = material
mesh_obj["type"] = "Mesh"
mesh_obj["shading"] = sh
mesh_obj["coloring"] = coloring
return self._Viewer__add_object(mesh_obj)
Would be used as
plt = mp.Viewer(dict())
add_transparent_mesh(plt, v,f)
love it, thanks! What is the purpose of f_tmp
? Isn't that just copying f
and then resetting f
, (as itself)? Or is it reordering the winding.
Hi,
That part I took from the original code (not really relevant to the transparent part I edited), and the purpose was: assuming f
is a tet mesh, split each to 4 triangles for visualize.