Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding transparency/opacity/alpha #30

Open
ljmartin opened this issue Apr 25, 2021 · 3 comments
Open

Adding transparency/opacity/alpha #30

ljmartin opened this issue Apr 25, 2021 · 3 comments

Comments

@ljmartin
Copy link

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

material = p3s.MeshStandardMaterial(map=tex, reflectivity=sh["reflectivity"], side=sh["side"],
which (I think) instantiates the mesh from pythreejs. Looks like the pythreejs MeshStandardMaterial does have an option alphaMap to handle transparency.

Thanks!
Lewis

@jiangzhongshi
Copy link
Contributor

jiangzhongshi commented Jul 1, 2021

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)

@ljmartin
Copy link
Author

ljmartin commented Jul 1, 2021

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.

@jiangzhongshi
Copy link
Contributor

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants