Files
trellis2-ROCm/trellis2_capi.h
T
2026-08-16 18:33:03 +07:00

224 lines
12 KiB
C

/*
** trellis2_capi.h — flat C ABI for embedding trellis2 in non-C++ hosts
** (the Go demo server dlopens libtrellis2.so and binds these by name).
**
** ABI version bumps whenever any signature or struct layout here changes.
*/
#pragma once
#include <stdint.h>
#ifdef TRELLIS2_SHARED
# if defined(_WIN32) && !defined(__MINGW32__)
# ifdef TRELLIS2_BUILD
# define TRELLIS2_CAPI __declspec(dllexport)
# else
# define TRELLIS2_CAPI __declspec(dllimport)
# endif
# else
# define TRELLIS2_CAPI __attribute__ ((visibility ("default")))
# endif
#else
# define TRELLIS2_CAPI
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define T2_CAPI_ABI_VERSION 11
TRELLIS2_CAPI int t2_abi_version(void);
/* Pipeline stages reported by the progress callback. */
enum t2_stage {
T2_STAGE_PREPROCESS = 0, /* image decode + crop/premultiply/resize */
T2_STAGE_DINO = 1, /* conditioning encoder */
T2_STAGE_SS_FLOW = 2, /* sparse-structure flow sampling (steps) */
T2_STAGE_SS_DEC = 3, /* occupancy decoder -> voxel scaffold */
T2_STAGE_SLAT_FLOW = 4, /* shape-SLAT flow sampling (steps) */
T2_STAGE_SHAPE_DEC = 5, /* shape decoder -> dual-grid fields */
T2_STAGE_MESH = 6, /* mesh extraction */
T2_STAGE_UPSAMPLE = 7, /* cascade: LR slat -> HR voxel scaffold */
T2_STAGE_SLAT_FLOW_HR = 8, /* cascade: 1024 shape-SLAT flow (steps) */
T2_STAGE_SHAPE_DEC_HR = 9, /* cascade: 1024^3 shape decoder */
T2_STAGE_TEXTURE = 10 /* PBR texture: flow + guided decode */
};
/* Pipeline type for t2_generate. */
enum t2_pipeline_type {
T2_PIPE_AUTO = 0, /* cascade if available, else 512 fine, else coarse */
T2_PIPE_COARSE = 1, /* 64^3 occupancy -> marching cubes preview */
T2_PIPE_512 = 2, /* 512 fine dual-grid */
T2_PIPE_1024 = 3 /* 1024 cascade */
};
/* Solid-background handling before the alpha-bbox crop. */
enum t2_background_mode {
T2_BACKGROUND_AUTO = 0, /* detect border-connected near-black/near-white */
T2_BACKGROUND_KEEP = 1, /* preserve the decoded alpha exactly */
T2_BACKGROUND_BLACK = 2, /* force removal of border-connected near-black */
T2_BACKGROUND_WHITE = 3 /* force removal of border-connected near-white */
};
/* Capability bits reported by t2_pipeline_caps (loaded qualities/features). */
enum t2_caps {
T2_CAP_COARSE = 1,
T2_CAP_512 = 2,
T2_CAP_1024 = 4,
T2_CAP_TEXTURE = 8
};
/* Load-time flags for t2_pipeline_load. */
enum t2_load_flags {
T2_LOAD_LOW_VRAM = 1 /* reserved: load DiTs on demand (follow-on) */
};
/* step/total are meaningful for T2_STAGE_SS_FLOW; other stages send 0/0 at
** entry. Called from the generating thread. */
typedef void (*t2_progress_fn)(void * user, int stage, int step, int total);
/* Optional live intermediate-preview callback. During generation the host
** receives self-describing geometry blobs (currently "T2VOX01": a voxel set —
** magic[8], u32 res, u32 nvox, u16[3*nvox] coords in [0,res)) for the current
** stage, so a viewer can show the shape emerging in 3D. `data` is valid only
** during the call (copy it). Fires on the generating thread. NULL disables it.
** See t2_generate. */
typedef void (*t2_preview_fn)(void * user, int stage, int step, int total,
const void * data, int len);
typedef struct t2_pipeline t2_pipeline;
typedef struct t2_mesh_result t2_mesh_result;
/* Load the pipeline models. Optional models (pass NULL/"" to omit) select the
** available qualities:
** - slat_flow_gguf + shape_dec_gguf present -> 512 fine dual-grid
** - + slat_hr_flow_gguf present -> 1024 cascade (reuses shape_dec)
** - shape_enc_gguf + tex_dec_gguf + tex_flow_gguf -> PBR texturing
** - neither pair -> coarse marching-cubes preview
** `flags` is a bitmask of t2_load_flags (0 for standard resident loading).
** On failure returns NULL and, if err != NULL, writes a reason into err. */
TRELLIS2_CAPI t2_pipeline * t2_pipeline_load(const char * dino_gguf,
const char * ss_flow_gguf,
const char * ss_dec_gguf,
const char * slat_flow_gguf,
const char * slat_hr_flow_gguf,
const char * shape_dec_gguf,
/* PBR texturing (optional; NULL/"" to disable). The tex
** models are loaded lazily per-generate, not held resident.
** The validated generation path uses shape_enc_gguf to
** re-encode the decoded dual grid before texture flow. */
const char * shape_enc_gguf,
const char * tex_dec_gguf,
const char * tex_flow_gguf,
const char * tex_flow_hr_gguf,
int flags,
char * err, int err_len);
/* Bitmask of t2_caps: which mesh qualities/features this pipeline can produce. */
TRELLIS2_CAPI int t2_pipeline_caps(t2_pipeline * p);
/* Back-compat: 1 if any fine (512/1024) path is available, else 0. */
TRELLIS2_CAPI int t2_pipeline_is_fine(t2_pipeline * p);
TRELLIS2_CAPI void t2_pipeline_free(t2_pipeline * p);
TRELLIS2_CAPI const char * t2_pipeline_backend(t2_pipeline * p);
/* image bytes (PNG/JPEG/...; anything stb_image decodes) -> triangle mesh.
** pipeline_type is a t2_pipeline_type (T2_PIPE_AUTO picks the best available).
** background_mode is a t2_background_mode (normally T2_BACKGROUND_AUTO).
** steps <= 0, guidance < 0, and texture_steps <= 0 select the pipeline defaults
** (12 / 7.5 / 12 respectively).
** `preview` (may be NULL) streams live intermediate 3D previews as the sparse
** structure emerges; `preview_user` is passed back to it. The T2_PREVIEW_STRIDE
** env var (default: ~4 previews across the SS steps) tunes the per-step cadence.
** NOT thread-safe per pipeline: serialize calls on one t2_pipeline. */
TRELLIS2_CAPI t2_mesh_result * t2_generate(t2_pipeline * p,
const void * image_bytes, int image_len,
int pipeline_type, int background_mode,
uint64_t seed, int steps, float guidance,
int texture_steps,
t2_progress_fn progress, void * user,
t2_preview_fn preview, void * preview_user,
char * err, int err_len);
/* Mesh accessors. Vertices are in a centered unit cube ([-0.5, 0.5]^3, same
** axes as the voxel grid); normals are per-vertex unit vectors. Buffers stay
** valid until t2_mesh_free. */
TRELLIS2_CAPI int t2_mesh_n_verts(const t2_mesh_result * r);
TRELLIS2_CAPI int t2_mesh_n_tris (const t2_mesh_result * r);
TRELLIS2_CAPI const float * t2_mesh_verts (const t2_mesh_result * r); /* 3*n_verts */
TRELLIS2_CAPI const float * t2_mesh_normals(const t2_mesh_result * r); /* 3*n_verts */
TRELLIS2_CAPI const int * t2_mesh_tris (const t2_mesh_result * r); /* 3*n_tris */
/* Per-vertex PBR (6*n_verts: base_color rgb, metallic, roughness, alpha), or NULL when
** the mesh is untextured. t2_mesh_has_pbr reports availability. */
TRELLIS2_CAPI int t2_mesh_has_pbr(const t2_mesh_result * r);
TRELLIS2_CAPI const float * t2_mesh_pbr (const t2_mesh_result * r); /* 6*n_verts */
TRELLIS2_CAPI void t2_mesh_free (t2_mesh_result * r);
/* Prepare the exact component-cleaned geometry used for export so hosts can preview it.
** component_filter: 0 removes only tiny islands; 1 keeps the largest connected
** component; 2 keeps all components. The returned mesh owns copied PBR and is
** freed with t2_mesh_free. */
TRELLIS2_CAPI t2_mesh_result * t2_prepare_mesh(const float * verts, int n_verts,
const int * tris, int n_tris,
const float * pbr,
int component_filter,
char * err, int err_len);
/* Optional CGAL Alpha Wrap print remeshing. Availability is fixed at build
** time. alpha_ratio and offset_ratio are fractions of the component-filtered
** input bounding-box diagonal (recommended starting point: 0.01 and
** 0.01/30). The returned geometry is watertight, oriented, intersection-free,
** 2-manifold, and geometry-only (no PBR) because wrapping creates new vertices.
** Use t2_bake_projected_glb to transfer source PBR onto its UV atlas. */
TRELLIS2_CAPI int t2_print_remesh_available(void);
TRELLIS2_CAPI t2_mesh_result * t2_prepare_print_mesh(const float * verts, int n_verts,
const int * tris, int n_tris,
const float * pbr,
int component_filter,
float alpha_ratio,
float offset_ratio,
char * err, int err_len);
/* Bake a mesh into a portable UV-atlas-textured GLB (glTF 2.0 binary): optional
** component cleanup -> UV unwrap -> per-texel PBR bake (from the dense
** per-vertex attributes) -> gutter inpaint -> glTF. All CPU, no CUDA.
** verts 3*n_verts, tris 3*n_tris, pbr 6*n_verts (base_color rgb, metallic,
** roughness, alpha) or NULL for an untextured grey bake.
** texture_size square atlas resolution hint (e.g. 2048; <=0 -> default).
** component_filter 0 remove tiny islands, 1 largest only, 2 keep all.
** Operates on raw arrays so hosts can bake straight from their own buffers.
** On success returns a malloc'd GLB buffer (free with t2_free_buffer) and writes
** its length to *out_len; on failure returns NULL with a reason in err. */
TRELLIS2_CAPI uint8_t * t2_bake_glb(const float * verts, int n_verts,
const int * tris, int n_tris,
const float * pbr,
int texture_size, int component_filter,
int * out_len, char * err, int err_len);
/* Bake a UV-atlas PBR GLB for replacement geometry by closest-surface
** projection from a dense source mesh. Every covered target atlas texel is
** projected to a source triangle and receives barycentrically interpolated
** source PBR. This is the CPU/CGAL counterpart of upstream's cuBVH rebake.
** source_component_filter has the same 0/1/2 values as component_filter above.
** Returns NULL when CGAL support is unavailable. */
TRELLIS2_CAPI uint8_t * t2_bake_projected_glb(
const float * target_verts, int target_n_verts,
const int * target_tris, int target_n_tris,
const float * source_verts, int source_n_verts,
const int * source_tris, int source_n_tris,
const float * source_pbr,
int texture_size, int source_component_filter,
int * out_len, char * err, int err_len);
TRELLIS2_CAPI void t2_free_buffer(uint8_t * buf);
/* Image decode + TRELLIS.2 preprocessing only (no models). out_rgb must hold
** out_size*out_size*3 bytes. Returns 0 on success, nonzero on failure (reason
** in err). This is the untrusted-input surface targeted by the fuzzers. */
TRELLIS2_CAPI int t2_preprocess_image_bytes(const void * image_bytes, int image_len,
int out_size, unsigned char * out_rgb,
char * err, int err_len);
#ifdef __cplusplus
}
#endif