simvx.core.graphics.mesh¶
Geometry data with procedural primitives.
High-level: Mesh.cube(), Mesh.sphere(), Mesh.cone() Low-level: Mesh(positions, indices, normals, texcoords) + interleaved_bytes()
Module Contents¶
Classes¶
Vertex data with optional GPU buffers. Pure data until renderer uploads. |
Data¶
API¶
- simvx.core.graphics.mesh.log¶
‘getLogger(…)’
- simvx.core.graphics.mesh.MeshSource¶
None
- class simvx.core.graphics.mesh.Mesh(positions, indices=None, normals=None, texcoords=None, topology='triangles')[source]¶
Vertex data with optional GPU buffers. Pure data until renderer uploads.
Create via class methods: Mesh.cube(), Mesh.sphere(), Mesh.cone(), Mesh.cylinder() Or from raw data: Mesh(positions, indices, normals, texcoords) Or load from a Wavefront OBJ: Mesh.from_obj(“model.obj”) Mesh.from_obj(Resource(“game.assets”, “ship.obj”))
The optional :attr:
factory_specrecords the call that produced a mesh ({"name": "cube", "kwargs": {"size": 1.0}}or{"name": "obj", "source": <spec>}) so scene serialisation can round-trip the mesh by replaying the factory.Initialization
- bounding_box() tuple[numpy.ndarray, numpy.ndarray][source]¶
Returns (min_corner, max_corner) as vec3 arrays.
- generate_normals() simvx.core.graphics.mesh.Mesh[source]¶
Compute smooth vertex normals from face geometry. Returns self.
Vectorised via
np.add.at: each face normal is scattered into the three vertex slots that share it, in the same order the per-triangle loop would have visited them. The result matches the prior implementation bit-for-bit because addition is commutative.
- classmethod cube(size: float = 1.0) simvx.core.graphics.mesh.Mesh[source]¶
Axis-aligned cube centered at origin. 24 vertices, 36 indices.
- classmethod sphere(radius: float = 1.0, rings: int = 16, segments: int = 16) simvx.core.graphics.mesh.Mesh[source]¶
UV sphere.
- classmethod cone(radius: float = 0.5, height: float = 1.0, segments: int = 16) simvx.core.graphics.mesh.Mesh[source]¶
Cone pointing up +Y, base centered at origin.
- classmethod cylinder(radius: float = 0.5, height: float = 1.0, segments: int = 16) simvx.core.graphics.mesh.Mesh[source]¶
Cylinder along +Y axis, centered at origin.
- classmethod extrude_path(centerline: list[tuple[float, float, float]] | numpy.ndarray, sides: int = 8, radius: float = 0.5, profile: numpy.ndarray | None = None, closed: bool = False) simvx.core.graphics.mesh.Mesh[source]¶
Sweep a profile (default: regular polygon) along a 3D centerline.
Builds a tube / ribbon mesh: the bread-and-butter primitive for racing tracks, river meshes, electric arcs, tentacles, and anything else that follows a polyline. HexGL hand-rolled ~80 LOC of NumPy ribbon code; this method replaces that with a single call.
Args: centerline:
(N, 3)sequence of world-space points. Must haveN >= 2. Successive duplicate points are tolerated (collapsed segments produce zero-length quads). sides: Number of segments around the tube. Default 8. Ignored ifprofileis supplied. radius: Radius of the default circular profile. Ignored whenprofileis supplied. profile: Optional(sides, 2)array of 2D points in the profile’s local frame (X = right, Y = up relative to the centerline tangent). WhenNonea regularsides-gon of the givenradiusis generated. closed: WhenTrue, the last centerline segment loops back to the first: useful for closed tracks. The profile orientation at the join is whatever the local frame returns; for racetracks pre-join the geometry yourself if you need smooth continuity.Returns: A
Meshwith positions, normals (vertex-averaged from face normals), texcoords (V along the path, U around the ring), and triangle indices.factory_specis set so the mesh round-trips through the scene serialiser.Example::
track = Mesh.extrude_path( centerline=[(0, 0, 0), (5, 0.5, -1), (8, 0, -6)], sides=12, radius=0.8, )
- classmethod load(source: simvx.core.graphics.mesh.MeshSource) simvx.core.graphics.mesh.Mesh[source]¶
Load a mesh from any supported source.
Currently delegates to :meth:
from_obj(only Wavefront OBJ is supported). The check is by file extension on the resolved path.
- classmethod from_obj(source: simvx.core.graphics.mesh.MeshSource) simvx.core.graphics.mesh.Mesh[source]¶
Load from Wavefront OBJ. Handles v/vt/vn/f directives.
Accepts
str/os.PathLike(filesystem path),- Class:
~simvx.core.Resource(package handle), or- Class:
importlib.resources.abc.Traversable(raw importlib.resources result).