pythreejs: How to render clipped surfaces as solid objects

235 Views Asked by At

I'd like to achieve what is described in https://stackoverflow.com/a/37093210 with pythreejs in JupyterLab instead of pure javascript.

Can I somehow subclass MeshPhongMaterial in python to add this change?

I am also happy to go the ShaderMaterial route (see https://github.com/jupyter-widgets/pythreejs/blob/master/examples/Shaders.ipynb) , if I would understand how to use vertexShader and fragmentShader so that is roughly looks like MeshStandarMaterial or MeshPhongMaterial (I need ambient and point lights and DoubleSide light support).

Of course, any other idea that gets me to what is depicted in https://stackoverflow.com/a/37093210 with pythreejs is welcome.

1

There are 1 best solutions below

0
On

It was surprisingly easy to port the SectionHelper mentioned in the answer https://stackoverflow.com/a/38186639

class SectionHelper(Mesh):
    def __init__(self, object, hexOrMaterial):
        if isinstance(hexOrMaterial, MeshBasicMaterial):
            material = hexOrMaterial
        else:
            color = hexOrMaterial
            material = MeshBasicMaterial(color=color, side="BackSide")

        super().__init__(object.geometry, material)

        self.matrix = object.matrixWorld
        self.matrixAutoUpdate = False

The result is then as expected

from ipywidgets import Layout
material = MeshPhongMaterial(color = "green", side="DoubleSide", diffuse="red")

torus = Mesh(
    TorusKnotBufferGeometry(radius=20, tube=5, tubularSegments=64, radialSegments=64, p=2, q=3), 
    material=material
)

sec = SectionHelper(torus, "#ff00ff")

key_light = DirectionalLight(color='white', position=[3, 5, 1], intensity=0.5)

c = PerspectiveCamera(position=[0, 100, 100], up=[0, 1, 0], children=[key_light])

scene = Scene(children=[torus, sec, c, AmbientLight(color='#777777')], background=None)

renderer = Renderer(camera=c, 
                    scene=scene,
                    alpha=True,
                    clearOpacity=0,
                    controls=[OrbitControls(controlling=c)],
                    width=500, height=500)

renderer.localClippingEnabled = True;
display(renderer)

for i in range(-64, 64):
    renderer.clippingPlanes = [Plane((0,-1,0), i/2.0)]
    time.sleep(0.1)

clipped torusknot