Wireframe

Draw a mesh’s edges with Material(wireframe=True).

▶ Run in browser

Tags: 3d

Material(wireframe=True) draws a mesh as the edges of its triangles instead of filled faces. The rest of the material still applies: colour, roughness and emission shade the edges the way they would shade a surface.

A cube and a sphere each spin beside a twin that shares its mesh and material settings, solid in the left column and wireframe in the right, so the same geometry reads filled on one side and as its edges on the other. A wireframe surface is see-through, so its far edges show through and it casts no shadow. The column headings are Text3D labels placed in the world above each column.

Source

 1# /// simvx
 2# web = { width = 960, height = 540 }
 3# ///
 4"""Wireframe: Draw a mesh's edges with Material(wireframe=True).
 5
 6`Material(wireframe=True)` draws a mesh as the edges of its triangles instead
 7of filled faces. The rest of the material still applies: colour, roughness
 8and emission shade the edges the way they would shade a surface.
 9
10A cube and a sphere each spin beside a twin that shares its mesh and material
11settings, solid in the left column and wireframe in the right, so the same
12geometry reads filled on one side and as its edges on the other. A wireframe
13surface is see-through, so its far edges show through and it casts no shadow.
14The column headings are `Text3D` labels placed in the world above each column.
15"""
16
17from simvx.core import (
18    Anchor,
19    Camera3D,
20    CanvasLayer,
21    DirectionalLight3D,
22    Label,
23    Material,
24    Mesh,
25    MeshInstance3D,
26    Node3D,
27    Quat,
28    Text3D,
29    Vec3,
30)
31from simvx.graphics import App
32
33SHAPES = (
34    (Mesh.box(size=1.3), (0.9, 0.35, 0.2, 1.0)),
35    (Mesh.sphere(radius=0.75, rings=12, segments=16), (0.25, 0.6, 0.95, 1.0)),
36)
37COLUMNS = ((-1.2, False, "solid"), (1.2, True, "wireframe"))
38
39
40class WireframeScene(Node3D):
41    def on_ready(self):
42        self.add_child(Camera3D(position=(0, 1.2, 6.5))).look_at(Vec3(0, 0, 0))
43        self.add_child(DirectionalLight3D(intensity=1.2))
44
45        self.spinners = []
46        for x, wireframe, heading in COLUMNS:
47            self.add_child(Text3D(text=heading, position=(x, 2.1, 0), font_scale=2.0))
48            for row, (mesh, colour) in enumerate(SHAPES):
49                material = Material(
50                    colour=colour,
51                    roughness=0.5,
52                    # A little emission keeps edges readable where they face away from the light.
53                    emissive_colour=tuple(c * 0.35 for c in colour[:3]),
54                    wireframe=wireframe,
55                )
56                node = MeshInstance3D(mesh=mesh, material=material, position=(x, 0.9 - row * 1.9, 0))
57                self.spinners.append(self.add_child(node))
58
59        hud = self.add_child(CanvasLayer())
60        hud.add_child(Label("Material(wireframe=True)", anchor=Anchor.TOP_LEFT, inset=16, font_size=22))
61
62    def on_update(self, dt: float):
63        t = self.tree.now
64        spin = Quat.from_euler(t * 0.3, t * 0.6, 0)
65        for node in self.spinners:
66            node.rotation = spin
67
68
69if __name__ == "__main__":
70    App(width=960, height=540, title="SimVX Wireframe").run(WireframeScene())