Metadata-Version: 2.4
Name: vcti-fileloader-slim
Version: 1.0.0
Summary: Fileloader plugin for CST SLIM (.slm/.slim) mesh files
Author: Visual Collaboration Technologies Inc.
Requires-Python: <3.15,>=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy
Requires-Dist: vcti-fileloader-mesh>=1.0.0
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Requires-Dist: pytest-cov; extra == "test"
Provides-Extra: lint
Requires-Dist: ruff; extra == "lint"
Provides-Extra: typecheck
Requires-Dist: mypy; extra == "typecheck"
Dynamic: license-file

# vcti-fileloader-slim

Fileloader plugin for CST SLIM (.slm/.slim) mesh files.

## Overview

`vcti-fileloader-slim` reads the SLIM mesh files written by CST Studio
Suite (`3d.slm`, `.slim`) into a
[mesh-schema](https://pypi.org/project/vcti-mesh-schema/) DataNode
subtree. SLIM is a PLY-derived binary format; `SlimLoader` (built on
[`vcti-fileloader-mesh`](https://pypi.org/project/vcti-fileloader-mesh/))
parses it directly in pure numpy — no CST DLL — and reads the edgeless
hex `3d.slm` files that CST's own SlimMeshReader rejects. Every
fixed-width element (`node`, `edge`, `triangle`, `tetrahedron`, ...)
becomes one **lazy structured-array block** whose shape and record dtype
come from the header, so a mesh is browsable without reading a byte of
body; block reads are zero-copy views into the file buffer. Point rows
keep file order, so a point's row index is its SLIM node index — the
`global_index` CST result readers use.

## Installation

```bash
pip install vcti-fileloader-slim
```

### In `requirements.txt`

```
vcti-fileloader-slim>=1.0.0
```

### In `pyproject.toml` dependencies

```toml
dependencies = [
    "vcti-fileloader-slim>=1.0.0",
]
```

---

## Quick Start

```python
from pathlib import Path
from vcti.fileloader.core import DataNode
from vcti.fileloader.slim import SlimLoader
from vcti.tree.core import DictTree

loader = SlimLoader()
tree = DictTree(root_data=DataNode())

with loader.open(Path("3d.slm")) as handle:
    mesh_root = loader.populate(handle, tree, tree.root_handle)
    # blocks are lazy — materialise what you touch, inside the open()
    for h in tree.children(mesh_root):
        p = tree.payload(h)
        print(p.name, p.shape, p.dtype)      # header facts, nothing read
```

The subtree conforms to the mesh schema, so its accessors apply directly:

```python
from vcti.mesh.schema import connectivity, coordinates, load_mesh_blocks

with loader.open(Path("3d.slm")) as handle:
    mesh_root = loader.populate(handle, tree, tree.root_handle)
    blocks = load_mesh_blocks(tree, mesh_root)   # materialises the blocks

xyz = coordinates(blocks["node"])                # (N, 3) float64
tri = connectivity(blocks["triangle"])           # (M, 3) int64
uid = blocks["node"]["uid"]                      # per-node id, row-aligned
```

Register it like any fileloader plugin:

```python
from vcti.fileloader.slim import get_loader_descriptor

registry.register(get_loader_descriptor())       # id: slim-numpy-loader
```

For header inspection without touching the body:

```python
from vcti.fileloader.slim import parse_header

header = parse_header(Path("3d.slm").read_bytes())
[(e.name, e.count) for e in header.elements]     # element inventory
```

---

## What it reads

| SLIM element | Becomes | Notes |
|--------------|---------|-------|
| `node` | `node` block | `x, y, z` + `uid`; file order = node index |
| `edge` / `triangle` / `tetrahedron` | cell blocks | `node_index*` connectivity + `uid` |
| `identification`, other fixed | blocks (ignored by schema) | attached, browsable |
| `list ...` (feature maps, curvature) | not parsed | names in the root's `unparsed_elements` |

See [docs/slim-format.md](docs/slim-format.md) for the format reference
and [docs/design.md](docs/design.md) for the design.

---

## Dependencies

- [vcti-fileloader-mesh](https://pypi.org/project/vcti-fileloader-mesh/) — mesh loader base and schema (brings vcti-fileloader and vcti-mesh-schema).
- [numpy](https://numpy.org/) — header-driven structured-array decoding.
