#ifndef HOLE_DETECTION_H #define HOLE_DETECTION_H #include "HoleDetectionParams.h" #include "ErrorCodes.h" #include "../include/VZNL_Types.h" // Export macro for Windows DLL #ifdef _WIN32 #ifdef HOLE_DETECTION_EXPORTS #define HOLE_DETECTION_API __declspec(dllexport) #else #define HOLE_DETECTION_API __declspec(dllimport) #endif #else #define HOLE_DETECTION_API #endif /** * @brief Boundary point with grid location (for debug callbacks) */ struct SHoleBoundaryPoint { SVzNLPointXYZ point; // 点坐标 int row; // 行号 int col; // 列号 SHoleBoundaryPoint() : point(), row(-1), col(-1) {} SHoleBoundaryPoint(const SVzNLPointXYZ& p, int r, int c) : point(p), row(r), col(c) {} }; /** * @brief Cluster information for debug callbacks */ struct SClusterInfo { const SHoleBoundaryPoint* points; // Points in this cluster int count; // Number of points in this cluster }; /** * @brief Debug callbacks for visualization and debugging * * All callbacks are optional (can be nullptr). * userData is passed to all callbacks for user context. */ struct SHoleDetectionDebugCallbacks { /** * @brief Called after boundary points are detected * @param points Array of boundary points * @param count Number of boundary points * @param userData User-provided context pointer */ void (*onBoundaryDetected)(const SHoleBoundaryPoint* points, int count, void* userData); /** * @brief Called after clustering is complete * @param clusters Array of cluster information * @param clusterCount Number of clusters found * @param userData User-provided context pointer */ void (*onClustersFound)(const SClusterInfo* clusters, int clusterCount, void* userData); /** * @brief Called when expanded region points are collected for plane fitting * @param clusterPoints Array of cluster boundary points * @param clusterCount Number of cluster points * @param expandedPoints Array of expanded region points (surrounding flat surface) * @param expandedCount Number of expanded region points * @param userData User-provided context pointer */ void (*onExpandedRegion)(const SHoleBoundaryPoint* clusterPoints, int clusterCount, const SVzNLPointXYZ* expandedPoints, int expandedCount, void* userData); /** * @brief Called after each hole is fitted * @param hole The fitted hole result * @param holeIndex Index of this hole (0-based) * @param userData User-provided context pointer */ void (*onHoleFitted)(const SHoleResult* hole, int holeIndex, void* userData); /** * @brief Called when segment endpoint pairs are detected * @param segmentPairs Array of segment pairs (each pair has start and end points) * @param count Number of segment pairs * @param userData User-provided context pointer */ void (*onSegmentPairsDetected)(const SSegmentPair* segmentPairs, int count, void* userData); /** * @brief User-provided context pointer, passed to all callbacks */ void* userData; }; /** * @brief Detect multiple holes in point cloud * * This is the main entry point for hole detection. It performs the following steps: * 1. Validate grid format * 2. Detect pit boundaries * 3. Cluster boundary points * 4. Fit ellipse and plane for each cluster * 5. Filter and sort results * * @param [in] points Input point cloud (grid format) * @param [in] rows Number of rows * @param [in] cols Number of columns * @param [in] detectionParams Detection parameters * @param [in] filterParams Filter parameters * @param [out] result Output result structure * @param [in] debugCallbacks Optional debug callbacks for visualization (can be nullptr) * @return 0 on success, non-zero on error * * @pre points != nullptr * @pre rows > 0 * @pre cols > 0 * @pre result != nullptr * * @post If return value is 0, result contains detected holes * @post Caller must free result->holes using delete[] */ HOLE_DETECTION_API int DetectMultipleHoles( const SVzNLPointXYZ* points, int rows, int cols, const SHoleDetectionParams& detectionParams, const SHoleFilterParams& filterParams, SMultiHoleResult* result, const SHoleDetectionDebugCallbacks* debugCallbacks = nullptr ); /** * @brief Print detection results to console in a formatted way * * @param [in] result Detection result structure * @param [in] verbose If true, print detailed information for each hole */ HOLE_DETECTION_API void PrintDetectionResults(const SMultiHoleResult& result, bool verbose = true); /** * @brief Print a single hole result to console * * @param [in] hole Single hole result * @param [in] index Hole index (for display purposes) */ HOLE_DETECTION_API void PrintHoleResult(const SHoleResult& hole, int index); #endif // HOLE_DETECTION_H