#ifndef GPU_SDF_H #define GPU_SDF_H #ifdef _WIN32 #ifdef GPU_OFFSET_EXPORTS #define GPU_SDF_API __declspec(dllexport) #else #define GPU_SDF_API __declspec(dllimport) #endif #else #define GPU_SDF_API __attribute__((visibility("default"))) #endif #ifdef __cplusplus extern "C" { #endif #include #include #include "gpu_offset.h" /** * @brief CSG Operation Types for GPU SDF combinations */ typedef enum { GPU_SDF_OP_UNION = 0, // A U B: max(d_A, d_B) GPU_SDF_OP_INTERSECTION = 1, // A ^ B: min(d_A, d_B) GPU_SDF_OP_DIFFERENCE = 2, // A \ B: min(d_A, -d_B) GPU_SDF_OP_SMOOTH_UNION = 3, // Smooth union with blend radius k GPU_SDF_OP_SMOOTH_INTERSECT= 4, // Smooth intersection with blend radius k GPU_SDF_OP_SMOOTH_DIFF = 5 // Smooth difference with blend radius k } GpuSdfOp; /** * @brief Layer matching policy when operating on two stacks */ typedef enum { GPU_SDF_LAYER_MATCH_A_DOMINANT = 0, // Keep layers matching stack A (resample B at A's Z) GPU_SDF_LAYER_MATCH_UNION = 1, // Output union of all unique layer Z heights GPU_SDF_LAYER_MATCH_INTERSECTION = 2 // Output only exact matching layer Z heights } GpuSdfLayerMatchMode; /** * @brief Procedural 3D Infill Pattern Types */ typedef enum { GPU_SDF_INFILL_SOLID = 0, GPU_SDF_INFILL_GRID = 1, GPU_SDF_INFILL_GYROID = 2, GPU_SDF_INFILL_SCHWARZ_P = 3, GPU_SDF_INFILL_SCHWARZ_D = 4 } GpuSdfInfillPattern; /** * @brief Spatial metadata for a 2D/3D GPU Signed Distance Field stack * All spatial coordinates and pitches are stored in integer micrometers (µm) */ typedef struct { int32_t min_x_um; // Minimum X bound in micrometers (1 µm = 0.001 mm) int32_t min_y_um; // Minimum Y bound in micrometers int32_t pitch_um; // Pixel raster pitch in micrometers (e.g. 100 µm = 0.1 mm) int width; // Grid columns (X) int height; // Grid rows (Y) size_t num_layers; // Total number of layers (Z) } GpuSdfMetadata; /** * @brief Opaque handle representing a GPU-resident Signed Distance Field stack. * Distance values are in millimeters (float): * d > 0 : Inside the object (positive Euclidean distance to boundary) * d < 0 : Outside the object (negative Euclidean distance to boundary) * d = 0 : Exact object boundary */ typedef struct GpuSdfStack_T* GpuSdfStackHandle; /** * @brief Create an empty GPU SDF stack with given metadata and layer Z heights (in µm). */ GPU_SDF_API GpuSdfStackHandle gpu_sdf_create( const GpuSdfMetadata* meta, const int32_t* layer_z_heights_um ); /** * @brief Create a GPU SDF stack from 3D mesh triangles directly on GPU. */ GPU_SDF_API GpuSdfStackHandle gpu_sdf_from_mesh( 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_mm, float first_layer_height_mm, float pitch_mm, float pad_mm ); /** * @brief Create a GPU SDF stack from raw host binary occupancy masks (0 = background, >0 = object). */ GPU_SDF_API GpuSdfStackHandle gpu_sdf_from_masks( const uint8_t* h_masks, int width, int height, size_t num_layers, const int32_t* layer_z_heights_um, int32_t min_x_um, int32_t min_y_um, int32_t pitch_um ); /** * @brief Clone an existing GPU SDF stack (allocates new GPU memory). */ GPU_SDF_API GpuSdfStackHandle gpu_sdf_clone(GpuSdfStackHandle stack); /** * @brief Free GPU memory allocated for a GPU SDF stack. */ GPU_SDF_API void gpu_sdf_destroy(GpuSdfStackHandle stack); /** * @brief Query metadata of a GPU SDF stack. */ GPU_SDF_API int gpu_sdf_get_metadata(GpuSdfStackHandle stack, GpuSdfMetadata* out_meta); /** * @brief Retrieve layer Z heights in micrometers (copies to host buffer of size num_layers). */ GPU_SDF_API int gpu_sdf_get_layer_z_um(GpuSdfStackHandle stack, int32_t* out_z_um); /** * @brief Retrieve raw SDF distance data (float mm) copied from GPU to Host. * Buffer size must be: width * height * num_layers * sizeof(float). */ GPU_SDF_API int gpu_sdf_to_host(GpuSdfStackHandle stack, float* h_out_data); /** * @brief Get raw GPU device pointer for zero-copy interop (CuPy / PyTorch). */ GPU_SDF_API float* gpu_sdf_get_device_ptr(GpuSdfStackHandle stack); /** * @brief Get raw GPU device pointer for layer Z heights (int32_t* on device). */ GPU_SDF_API int32_t* gpu_sdf_get_device_z_ptr(GpuSdfStackHandle stack); /** * @brief Execute a CSG operation between two GPU SDF stacks without host roundtrips. * Handles spatial bounding box differences and layer Z matching automatically. * * @param a First operand stack (GPU) * @param b Second operand stack (GPU) * @param op CSG operation (UNION, INTERSECTION, DIFFERENCE, SMOOTH_...) * @param match_mode Layer Z matching mode * @param blend_radius_mm Blend radius parameter for smooth operations * @return GpuSdfStackHandle Resulting stack on GPU (caller must free with gpu_sdf_destroy) */ GPU_SDF_API GpuSdfStackHandle gpu_sdf_csg_op( GpuSdfStackHandle a, GpuSdfStackHandle b, GpuSdfOp op, GpuSdfLayerMatchMode match_mode, float blend_radius_mm ); /** * @brief Apply a constant distance offset (dilation/expansion if delta > 0, inset/erosion if delta < 0). */ GPU_SDF_API GpuSdfStackHandle gpu_sdf_offset( GpuSdfStackHandle stack, float delta_mm ); /** * @brief Apply hollowing / shelling with a given wall thickness. */ GPU_SDF_API GpuSdfStackHandle gpu_sdf_shell( GpuSdfStackHandle stack, float thickness_mm ); /** * @brief Generate a procedural 3D infill pattern intersected with the interior region. */ GPU_SDF_API GpuSdfStackHandle gpu_sdf_generate_infill( GpuSdfStackHandle stack, GpuSdfInfillPattern pattern, float cell_size_mm, float density_ratio, float wall_offset_mm ); /** * @brief Vectorize GPU SDF stack directly to polygon perimeter contours and infill mask. */ GPU_SDF_API int gpu_sdf_vectorize( GpuSdfStackHandle stack, const GpuOffsetConfig* config, GpuLayerResult** out_results, size_t* out_num_layers, GpuOffsetStats* stats ); #ifdef __cplusplus } #endif #endif // GPU_SDF_H