Vtx (Where the triangles are)

class valvemdl.Vtx(path=None)[source]

Contains the data from a vtx file.

An mdl carries no triangle indices; they all live here, arranged into the strips and stripgroups the graphics hardware draws. The header is parsed when the file is opened; the tree below it is large, so it is walked on first access to bodyparts and cached.

The tree mirrors the mdl’s bodypart / model / mesh levels one to one, which is the check Mdl.validate uses to tie the two files together. Below a mesh the vtx adds what the mdl does not have: stripgroups, strips, and the index buffer that assembles the vvd’s vertices into triangles.

__init__(path=None)[source]

Creates an empty instance of Vtx.

Parameters:

path (str, optional) – A path to an existing vtx file.

source_path
Type:

(str) - The location of the parsed file.

header
Type:

(construct.Container) - The parsed FileHeader_t.

property checksum

Note the field is spelled checkSum in the vtx header and checksum everywhere else. This property smooths that over; the struct keeps the format’s spelling.

Type:

(int) - Ties this vtx to its mdl and vvd.

property bodyparts

The optimized mesh tree, walked on first access.

Each bodypart carries .models, each model .lods, each lod .meshes, each mesh .stripgroups. A stripgroup carries .vertices (Vertex_t), .indices (the unsigned short index buffer) and .strips, and each strip its .bonestatechanges.

Type:

(list[construct.Container]) - The bodyparts.

property material_replacements

The per-lod material replacement tables.

One MaterialReplacementListHeader_t per lod, each holding replacements that swap a material out at that detail level – how the engine drops to cheaper materials at distance.

Type:

(list[construct.Container]) - One entry per lod.

validate()[source]

Checks the vtx’s internal invariants.

Reports rather than raises, like the mdl and vvd do. Every check is structural – counts add up, strips stay inside their stripgroup, the index buffer points at vertices that exist – so a vtx that fails one is worth looking at.

Returns:

One string per broken invariant, empty when sound.

Return type:

list[str]

save(destination=None)[source]

Writes the vtx back out, rebuilt from its tree.

Parameters:

destination (str, optional) – Where to write. Overwrites the original when not given.

coverage()[source]

How much of the vtx ValveMDL can account for.

Like the vvd and unlike the mdl, a sound vtx comes back essentially all struct: it has no compressed regions, so every byte is regenerated rather than copied.

Returns:

Byte counts, plus differ: bytes the rebuild got wrong.

Return type:

dict

__repr__()[source]

Return repr(self).