> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ntop.com/llms.txt
> Use this file to discover all available pages before exploring further.

# API Reference

This page documents the public API of `ntop.core`. All coordinates and distances are in meters.

## Loading a body

### `ntop.core.load`

```python theme={null}
load(path: str | os.PathLike) -> ImplicitBody
```

Loads an implicit body from a `.implicit` file. Triggers process-wide one-shot initialization of the engine's dependencies on the first call.

* **Raises** `FileNotFoundError` if the file does not exist, `PermissionError` if it cannot be opened, `ValueError` if the file is corrupt or an unsupported version.

```python theme={null}
>>> import ntop.core as core
>>> body = core.load("part.implicit")
>>> body.bounding_box.diagonal
array([0.1, 0.1, 0.1])
```

`ImplicitBody` releases its native handle automatically when garbage collected, or immediately via a context manager:

```python theme={null}
with core.load("part.implicit") as body:
    values = body.field(points)
# handle released here
```

## `ImplicitBody`

### Properties

| Property       | Type          | Description                                                          |
| -------------- | ------------- | -------------------------------------------------------------------- |
| `path`         | `str \| None` | Path this body was loaded from, or `None` if not loaded from a file. |
| `bounding_box` | `BoundingBox` | Axis-aligned bounding box of the body.                               |

### `field`

```python theme={null}
field(points: NDArray[float64]) -> NDArray[float64]
```

Evaluates the implicit field at an array of points. Negative inside the body, positive outside.

* `points`: shape `(N, 3)` or `(3,)`. A single `(3,)` point returns a scalar rather than a length-1 array.
* **Raises** `ValueError` for the wrong shape, `ReferenceError` if the handle was already released.

```python theme={null}
>>> body.field(np.zeros((3, 3)))
array([-0.05, -0.05, -0.05])
```

### `gradient`

```python theme={null}
gradient(points: NDArray[float64]) -> GradientResult
```

Evaluates the field value and its gradient at an array of points in one native call.

* `points`: shape `(N, 3)` or `(3,)`.
* **Returns** a `GradientResult(values, gradient)`. `gradient` has shape `(N, 3)` (or `(3,)` for a single point); its magnitude is 1 everywhere except the medial axis for a signed-distance field.
* **Raises** `ValueError` for the wrong shape, `ReferenceError` if the handle was already released.

### `mesh`

```python theme={null}
mesh(*, feature_size: float, adaptivity: float = 0.0) -> TriangleMesh
```

Generates a triangle mesh via Dual Contouring.

* `feature_size`: sampling granularity in meters; smaller is finer. Must be positive.
* `adaptivity`: decimation tolerance. `0` disables decimation; negative values are clamped to `0`.
* **Returns** a `TriangleMesh` (always non-empty).
* **Raises** `ValueError` if `feature_size` is not positive, `RuntimeError` if meshing produced zero geometry (empty body, or `feature_size` too coarse), `ReferenceError` if the handle was already released.

<Note>Respects `KeyboardInterrupt` when called from the main thread: meshing runs on a worker thread while the caller polls for signals.</Note>

### `slice`

```python theme={null}
slice(z: float, *, feature_size: float, method: str = "dc") -> list[NDArray[float64]]
```

Generates 2D contours at height `z` in the body's XY plane.

* `feature_size`: sampling granularity in meters. Must be positive.
* `method`: `"dc"` (Dual Contouring, default) or `"ms"` (Marching Squares).
* **Returns** a list of `(K, 2)` arrays, one per contour. An empty list is a valid result (e.g. `z` outside the body) and does not raise.
* **Raises** `ValueError` if `feature_size` is not positive or `method` is unrecognized, `ReferenceError` if the handle was already released.

### `voxelize`

```python theme={null}
voxelize(*, spacing: float, dimensions: tuple[float, float, float] | None = None, frame: Frame | None = None) -> NDArray[bool_]
```

Samples inside/outside classification on a 3D regular grid, built purely on top of `field` (no additional engine call).

* `spacing`: distance between sample points in meters along all three axes. Must be positive.
* `dimensions`: physical `(width, height, depth)` of the sampling volume. Defaults to the body's bounding box projected onto the frame axes.
* `frame`: orientation and origin of the sampling volume. Defaults to world-aligned axes with origin at `bounding_box.min`.
* **Returns** a `(nx, ny, nz)` boolean array, `True` = inside. Streams one Z-slice at a time, so peak memory is `O(nx * ny)` rather than `O(nx * ny * nz)`.
* **Raises** `ValueError` if `spacing` or a `dimensions` entry is not positive, `ReferenceError` if the handle was already released.

### `rasterize`

```python theme={null}
rasterize(*, spacing: float, dimensions: tuple[float, float] | None = None, frame: Frame | None = None, isovalue: float = 0.0) -> NDArray[bool_]
```

Samples inside/outside classification on a 2D regular grid (`ntop_core_fast_inout_query`).

* `spacing`: distance between sample points in meters. Must be positive.
* `dimensions`: physical `(width, height)` of the sampling window. Defaults to the bounding box projected onto the frame axes.
* `frame`: orientation and origin of the grid. Defaults to the world XY plane at the body's center z-height.
* `isovalue`: offsets the body before sampling; positive expands, negative contracts.
* **Returns** a `(height, width)` boolean array, row-major, origin bottom-left.
* **Raises** `ValueError` if `spacing` or a `dimensions` entry is not positive, `ReferenceError` if the handle was already released.

### `closest_point`

```python theme={null}
closest_point(points: NDArray[float64], tolerance: float) -> tuple[NDArray[float64], NDArray[uint32]]
```

Projects points onto the body surface via gradient-descent / bisection (max 500 iterations per point).

* `points`: shape `(N, 3)`.
* `tolerance`: convergence threshold in meters. Must be positive.
* **Returns** `(projected, out_of_tolerance)`: best-effort projected positions for every input point, and the indices that did not converge within `tolerance` (empty if all converged).
* **Raises** `ValueError` for the wrong shape or non-positive `tolerance`, `ReferenceError` if the handle was already released.

### `interval`

```python theme={null}
interval(bbox: BoundingBox) -> tuple[float, float]
```

Computes conservative field bounds `(lower, upper)` over a bounding box region. Same-sign bounds mean the region is strictly inside or outside the body; mixed-sign bounds do not guarantee a zero crossing exists.

* **Raises** `ReferenceError` if the handle was already released.

### `transform`

```python theme={null}
transform(frame: Frame) -> ImplicitBody
```

Applies a rigid-body transform, returning a new `ImplicitBody`. This body is unchanged.

Uses a passive-transform (pull-back) convention: `frame.origin` is the point in the old body's space that maps to `[0, 0, 0]` in the new space. To translate by `+d`, set `frame.origin = -d`.

* **Raises** `ReferenceError` if the handle was already released.

### `scale`

```python theme={null}
scale(factors: NDArray[float64], pivot: NDArray[float64]) -> ImplicitBody
```

Applies non-uniform scaling relative to a fixed `pivot` point, returning a new `ImplicitBody`. This body is unchanged.

* `factors`, `pivot`: shape `(3,)`.
* **Raises** `ValueError` if either argument is not shape `(3,)`, `ReferenceError` if the handle was already released.

<Note>The field is only exactly preserved as a signed-distance field for uniform scale. Non-uniform scale approximates it by rescaling with `cbrt(sx * sy * sz)`.</Note>

### `save`

```python theme={null}
save(path: str | os.PathLike) -> None
```

Saves this implicit body to a `.implicit` file.

* **Raises** `OSError` if the file could not be written, `ReferenceError` if the handle was already released.

## Data types

### `BoundingBox`

Axis-aligned bounding box, in meters.

| Field      | Type                             | Description                   |
| ---------- | -------------------------------- | ----------------------------- |
| `min`      | `NDArray[float64]`, shape `(3,)` | Minimum corner.               |
| `max`      | `NDArray[float64]`, shape `(3,)` | Maximum corner.               |
| `center`   | `NDArray[float64]`, shape `(3,)` | `(min + max) / 2` (property). |
| `diagonal` | `NDArray[float64]`, shape `(3,)` | `max - min` (property).       |

### `Frame`

A local coordinate frame, used by `transform`, `voxelize`, and `rasterize`.

| Field    | Type                             | Description                                        |
| -------- | -------------------------------- | -------------------------------------------------- |
| `origin` | `NDArray[float64]`, shape `(3,)` | Translation, in meters.                            |
| `x_axis` | `NDArray[float64]`, shape `(3,)` | Unit vector, orthogonal to `y_axis`.               |
| `y_axis` | `NDArray[float64]`, shape `(3,)` | Unit vector, orthogonal to `x_axis`.               |
| `z_axis` | `NDArray[float64]`, shape `(3,)` | `x_axis cross y_axis` (property, right-hand rule). |

`x_axis` and `y_axis` are validated as unit vectors and as a mutually orthogonal pair at construction (`ValueError` if not).

### `GradientResult`

Named tuple returned by `gradient`.

| Field      | Type                               | Description                                  |
| ---------- | ---------------------------------- | -------------------------------------------- |
| `values`   | `NDArray[float64]`                 | Field values, same as `field()`.             |
| `gradient` | `NDArray[float64]`, shape `(N, 3)` | Field gradient `(dx, dy, dz)` at each point. |

### `TriangleMesh`

Returned by `mesh`.

| Field      | Type                               | Description                                                     |
| ---------- | ---------------------------------- | --------------------------------------------------------------- |
| `vertices` | `NDArray[float64]`, shape `(N, 3)` | Vertex positions, in meters.                                    |
| `faces`    | `NDArray[uint32]`, shape `(M, 3)`  | Triangle indices, clockwise winding (`AB × AC` points outward). |

Also unpacks positionally: `vertices, faces = body.mesh(feature_size=0.001)`.

## Exceptions

All exceptions raised by `ntop.core` are standard Python builtins (`ValueError`, `FileNotFoundError`, `PermissionError`, `MemoryError`, `RuntimeError`, `ReferenceError`, `OSError`). See each method's **Raises** entry above for which one applies and when.
