cudaslicer/include/gpu_offset.h
2026-09-26 14:20:07 +03:00

214 lines
6.1 KiB
C

#ifndef GPU_OFFSET_H
#define GPU_OFFSET_H
#ifdef _WIN32
#ifdef GPU_OFFSET_EXPORTS
#define GPU_OFFSET_API __declspec(dllexport)
#else
#define GPU_OFFSET_API __declspec(dllimport)
#endif
#else
#define GPU_OFFSET_API __attribute__((visibility("default")))
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <stdint.h>
/**
* @brief Status and Error Codes
*/
#define GPU_OFFSET_SUCCESS 0
#define GPU_OFFSET_ERR_GENERIC -1
#define GPU_OFFSET_ERR_NO_CUDA -2
#define GPU_OFFSET_ERR_INVALID_ARG -3
/**
* @brief Compute Backend Modes
*/
typedef enum {
GPU_OFFSET_BACKEND_AUTO = 0, // Auto: use CUDA if available, fallback to CPU
GPU_OFFSET_BACKEND_CUDA = 1, // Require CUDA: returns GPU_OFFSET_ERR_NO_CUDA if unavailable
GPU_OFFSET_BACKEND_CPU = 2 // Compatibility mode: force multi-threaded CPU execution
} GpuOffsetBackend;
/**
* @brief 2D Point structure (floating-point millimeters)
*/
typedef struct {
float x;
float y;
} GpuPoint2D;
/**
* @brief 2D Polygon Contour Loop
*/
typedef struct {
GpuPoint2D* points;
size_t num_points;
int is_hole; // 0 = exterior boundary, 1 = interior hole
} GpuContour;
/**
* @brief Sliced Layer containing one or more planar polygon loops
*/
typedef struct {
GpuContour* contours;
size_t num_contours;
float z_height;
} GpuSliceLayer;
/**
* @brief Resulting Offset Contours for a single offset perimeter
*/
typedef struct {
GpuContour* contours;
size_t num_contours;
float offset_distance_mm;
} GpuOffsetPerimeter;
/**
* @brief Infill region mask and boundary contours for a single sliced layer
*/
typedef struct {
GpuContour* contours; // Infill boundary contours (at -perimeters_count * layer_width)
size_t num_contours;
uint8_t* mask; // 2D binary raster mask (width * height uint8), or NULL if not exported
int width;
int height;
float offset_distance_mm; // Offset distance for infill (perimeters_count * layer_width)
} GpuInfillRegion;
/**
* @brief All offset perimeters and infill mask for a single sliced layer
*/
typedef struct {
GpuOffsetPerimeter* perimeters; // Array of perimeters (length = num_perimeters)
size_t num_perimeters; // perimeters_count
GpuInfillRegion infill; // Infill boundary contours & 2D mask
float z_height;
} GpuLayerResult;
/**
* @brief Configuration parameters for Offsetting & Slicing Engine
*/
typedef struct {
float pitch_mm; // Pixel raster pitch (default: 0.10 mm)
float pad_mm; // Bounding box padding margin in mm (default: 1.5 mm)
int perimeters_count; // Number of perimeter passes (e.g. 2, default: 2)
float layer_width; // Line/extrusion width in mm (e.g. 0.45 mm, default: 0.45 mm)
const float* offset_distances_mm; // Optional custom offset distances (if NULL, auto-generated from perimeters_count & layer_width)
size_t num_offsets; // Total offsets (auto-set if offset_distances_mm is NULL)
int use_gpu_rasterizer; // 1 = GPU-accelerated rasterization (when CUDA enabled), 0 = CPU multi-threaded
float first_layer_height; // First layer height in mm (default: 0.0f -> uses layer_height)
int export_infill_mask; // 1 = export binary 2D infill mask into GpuLayerResult (default: 1)
float simplify_tolerance_mm; // RDP simplification tolerance in mm (default: 0.02 mm, 0 to disable)
int subpixel_lerp; // 1 = Continuous SDF sub-pixel LERP vectorization (default: 1), 0 = discrete bitpack
int backend; // GpuOffsetBackend: 0 = AUTO, 1 = CUDA, 2 = CPU (default: 0)
} GpuOffsetConfig;
/**
* @brief Microsecond-accurate timing breakdown
*/
typedef struct {
double t_mesh_slice_ms;
double t_raster_ms;
double t_h2d_ms;
double t_gpu_jfa_ms;
double t_gpu_thresh_ms;
double t_d2h_ms;
double t_vectorize_ms;
double t_total_pipeline_ms;
} GpuOffsetStats;
/**
* @brief Returns 1 if a functional CUDA-capable device is detected, 0 otherwise.
*/
GPU_OFFSET_API int gpu_offset_has_cuda(void);
/**
* @brief Set global default backend (0 = AUTO, 1 = CUDA, 2 = CPU).
*/
GPU_OFFSET_API int gpu_offset_set_backend(int backend);
/**
* @brief Get global default backend (0 = AUTO, 1 = CUDA, 2 = CPU).
*/
GPU_OFFSET_API int gpu_offset_get_backend(void);
/**
* @brief Initialize GPU device and allocate CUDA stream / warm up kernels.
*/
GPU_OFFSET_API int gpu_offset_init(int device_id);
/**
* @brief Core Distance Field & Offsetting on raw 2D/3D binary masks (CUDA or CPU fallback).
*/
GPU_OFFSET_API int gpu_offset_compute_masks(
const uint8_t* h_masks,
int width,
int height,
int num_layers,
float pitch_mm,
const float* offset_distances,
int num_offsets,
uint8_t* h_out_masks,
GpuOffsetStats* stats
);
/**
* @brief 3D Triangle structure for direct mesh slicing (vertices in millimeters)
*/
typedef struct {
float v0[3];
float v1[3];
float v2[3];
} GpuTriangle3D;
/**
* @brief End-to-end polygon offsetting: Polygons -> Raster -> Distance Field -> Vector Contours & Infill
*/
GPU_OFFSET_API int gpu_offset_polygon_layers(
const GpuSliceLayer* in_layers,
size_t num_layers,
float min_x, float min_y, float max_x, float max_y,
const GpuOffsetConfig* config,
GpuLayerResult** out_results,
GpuOffsetStats* stats
);
/**
* @brief End-to-End Mesh Slicing & Perimeter Offsetting:
* 3D Triangles -> Mesh Slicer -> Distance Field -> Vector Contours & Infill.
*/
GPU_OFFSET_API int gpu_offset_slice_mesh_and_offset(
const GpuTriangle3D* triangles,
size_t num_triangles,
float min_x, float min_y, float min_z,
float max_x, float max_y, float max_z,
float layer_height,
float first_layer_height,
const GpuOffsetConfig* config,
GpuLayerResult** out_results,
size_t* out_num_layers,
GpuOffsetStats* stats
);
/**
* @brief Free memory allocated for GpuLayerResult
*/
GPU_OFFSET_API void gpu_offset_free_results(GpuLayerResult* results, size_t num_layers);
/**
* @brief Release GPU context and cached buffers
*/
GPU_OFFSET_API void gpu_offset_cleanup();
#ifdef __cplusplus
}
#endif
#endif // GPU_OFFSET_H