#pragma once // 基础OTK头文件 - 确保正确的包含顺序 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Prevent Windows macro conflicts with std::min/max #ifdef max #undef max #endif #ifdef min #undef min #endif // Creo状态信息结构 struct CreoStatus { bool is_connected = false; std::string version; std::string build; std::string working_directory; int session_id = 0; }; // 模型状态信息结构 struct ModelStatus { bool has_model = false; std::string name; std::string filename; std::string type; std::string software; // 从OTK API获取,不设默认值 std::string version; // 从OTK API获取,不设默认值 std::string connection_time; bool is_assembly = false; int total_parts = 0; int assembly_levels = 0; std::string file_size; std::string connection_status; std::string open_time; bool is_modified = false; // 模型是否已修改(未保存) }; // 导出结果结构 struct ExportResult { bool success = false; std::string export_path; std::string file_size; std::string format; std::string export_time; std::string software; std::string original_file; std::string dirname; std::string filename; std::string error_message; }; // 保存结果结构 struct SaveResult { bool success = false; std::string file_size; std::string save_time; std::string software; std::string original_file; std::string error_message; }; // 关闭结果结构 struct CloseResult { bool success = false; std::string model_name; bool was_modified = false; std::string close_time; std::string error_message; }; // 打开结果结构 struct OpenResult { bool success = false; std::string model_name; std::string model_type; std::string file_path; std::string file_size; std::string open_time; bool is_assembly = false; int total_parts = 0; bool model_in_session = false; // 验证模型是否真的在会话中 bool window_model_match = false; // 验证窗口是否正确关联模型 std::string error_message; }; // 层级分析组件信息结构 struct ComponentInfo { std::string id; std::string name; std::string type; // "assembly" 或 "part" int level; int children_count; std::string path; std::string file_size; std::string deletion_safety; // "forbidden", "risky", "moderate" bool is_visible; std::string model_type; // "MDL_ASSEMBLY", "MDL_PART", "MDL_DRAWING" 等 std::string full_path; // 完整的组件路径 }; // 层级分析请求结构 struct HierarchyAnalysisRequest { std::string software_type; std::string project_name; int max_depth; bool include_geometry; int target_level = -1; // 新增:指定返回的层级,-1表示返回所有 std::map analysis_options; }; // 删除建议结构 struct DeletionRecommendation { std::string component_id; std::string component_name; int level; std::string reason; std::vector risk_factors; double confidence; }; // 层级分析结果结构 struct HierarchyAnalysisResult { bool success = false; std::string message; std::string project_name; int total_levels; int total_components; std::vector> hierarchy; std::vector safe_deletions; std::vector risky_deletions; std::string error_message; }; // Shell Analysis Constants namespace ShellAnalysisConstants { // Confidence thresholds constexpr double CONFIDENCE_STANDARD_PART = 0.99; constexpr double CONFIDENCE_INTERNAL_CUT = 0.95; constexpr double CONFIDENCE_INTERNAL_HOLE = 0.90; constexpr double CONFIDENCE_INTERNAL_GENERIC = 0.80; constexpr double CONFIDENCE_SHELL_FEATURE = 0.20; constexpr double CONFIDENCE_EXTERNAL_FEATURE = 0.05; // Performance thresholds constexpr int LARGE_MODEL_THRESHOLD = 500; constexpr int VERY_LARGE_MODEL_THRESHOLD = 1000; constexpr double SAMPLING_RATIO_FAST = 0.1; constexpr double SAMPLING_RATIO_STANDARD = 0.33; // Geometry calculation weights constexpr double VOLUME_WEIGHT = 0.5; constexpr double SURFACE_WEIGHT = 0.3; constexpr double BBOX_WEIGHT = 0.2; // Batch processing constexpr int BATCH_SIZE = 50; constexpr int MAX_PARALLEL_FEATURES = 100; // Cache settings constexpr int CACHE_TTL_SECONDS = 600; // 10 minutes constexpr int MAX_CACHE_SIZE = 1000; } // Analysis modes for large models enum ShellAnalysisMode { SHELL_ANALYSIS_FAST = 0, // Fast mode: sampling analysis SHELL_ANALYSIS_STANDARD = 1, // Standard mode: normal analysis SHELL_ANALYSIS_DETAILED = 2 // Detailed mode: full analysis }; // Creo管理器类 class CreoManager { public: // 会话管理(避免重复代码) struct SessionInfo { pfcSession_ptr session; wfcWSession_ptr wSession; bool is_valid; std::string version; std::string build; }; static CreoManager& Instance(); // 状态检测 CreoStatus GetCreoStatus(); ModelStatus GetModelStatus(); // 基础操作 bool ShowMessage(const std::string& message); // 导出功能 ExportResult ExportModelToSTEP(const std::string& export_path, const std::string& geom_flags = "solids"); // 保存功能 SaveResult SaveModel(); // 关闭功能 CloseResult CloseModel(bool force_close = false); // 打开功能 OpenResult OpenModel(const std::string& file_path, const std::string& open_mode = "active"); // 层级分析功能 HierarchyAnalysisResult AnalyzeModelHierarchy(const HierarchyAnalysisRequest& request); // 层级删除功能 struct HierarchyDeleteResult { bool success = false; std::string message; int original_levels; int target_level; int final_levels; std::map> deleted_components; int total_deleted; int successful; int failed; std::string error_message; }; HierarchyDeleteResult DeleteHierarchyComponents(const std::string& project_name, int target_level); // 子装配体层级删除功能 - 以指定子装配体为顶层进行层级删除 HierarchyDeleteResult DeleteSubassemblyHierarchyComponents(const std::string& subassembly_path, int target_level); // 薄壳化分析功能 struct ShellAnalysisRequest { std::string software_type; std::string project_name = "current_model"; std::string analysis_type = "surface_shell"; bool preserve_external_surfaces = true; double min_wall_thickness = 1.0; double confidence_threshold = 0.75; }; struct FeatureDeletion { int id; std::string name; std::string type; std::string reason; double confidence; double volume_reduction; // Changed from int to double for better precision std::string part_file; std::string part_path; std::string component_type = "FEATURE"; std::string volume_units = "percentage"; // Added to clarify units int vote_count = 0; // Number of votes this component received in multi-directional projection analysis }; struct EstimatedReduction { std::string volume_reduction; std::string file_size_reduction; std::string performance_improvement; }; struct HierarchyAnalysisInfo { bool enabled = true; int total_parts = 0; int outer_parts = 0; int internal_parts = 0; int containment_relationships = 0; std::map performance_stats; }; struct ShellAnalysisParameters { bool preserve_external_surfaces = true; double min_wall_thickness = 1.0; double confidence_threshold = 0.7; int total_features = 0; int deletable_features = 0; int preserved_features = 0; bool assembly_analysis = false; std::string analysis_strategy = "multi_directional_projection_analysis"; int surface_count = 0; int shell_surfaces = 0; int internal_surfaces = 0; int shell_feature_whitelist = 0; HierarchyAnalysisInfo hierarchy_analysis; }; // New structure for enhanced shell analysis struct ShellAnalysisItem { std::string name; std::string type; int feature_id; double confidence; std::string recommendation; std::string reason; std::string path; // 组件完整路径 bool is_deletable = false; double volume_percentage = 0.0; // Component volume percentage }; struct ShellAnalysisResult { bool success = false; std::vector safe_deletions; std::vector suggested_deletions; std::vector preserve_list; EstimatedReduction estimated_reduction; ShellAnalysisParameters analysis_parameters; std::string error_message; // Enhanced fields for new algorithm std::vector features; int total_features_analyzed = 0; int shell_features_count = 0; int internal_features_count = 0; int total_deletable = 0; double deletion_percentage = 0.0; std::string model_name; // OBB optimization statistics int obb_usage_count = 0; int aabb_usage_count = 0; double obb_usage_percentage = 0.0; }; ShellAnalysisResult AnalyzeShellFeatures(const ShellAnalysisRequest& request); ShellAnalysisResult AnalyzeShellFeaturesEnhanced(const ShellAnalysisRequest& request); // 薄壳化分析辅助方法 std::string GetFeatureTypeName(pfcFeatureType feat_type); bool IsExternalSurface(pfcFeature_ptr feature, bool preserve_external); bool CheckWallThickness(pfcFeature_ptr feature, double min_thickness); // 薄壳化算法辅助方法(基于真实OTK数据) bool IsStandardPart(const std::string& part_name); bool IsInternalPart(pfcFeature_ptr feature, pfcModel_ptr model); // 智能边界检测算法 bool IsOnAssemblyBoundary(pfcFeature_ptr component, pfcOutline3D_ptr assembly_bbox, double tolerance); double CalculateBoundaryOverlap(pfcOutline3D_ptr comp_bbox, pfcOutline3D_ptr assembly_bbox, double tolerance); double GetOptimalTolerance(pfcOutline3D_ptr assembly_bbox); // 真实几何计算方法 double CalculateFeatureVolumeImpact(pfcFeature_ptr feature, pfcSolid_ptr solid); std::vector CalculateBatchFeatureVolumeImpacts( const std::vector& features, pfcSolid_ptr solid, int batch_size = 10); // LOO (Leave-One-Out) attribution for accurate feature impact calculation std::vector CalculateLOOAttribution( const std::vector& features, pfcSolid_ptr solid, int top_k = 10); // Check feature proximity to external surface double CheckFeatureProximityToSurface( pfcFeature_ptr feature, pfcSolid_ptr solid, double min_thickness); // Enhanced geometric boundary detection functions bool AnalyzeFeatureGeometryEnhanced( pfcFeature_ptr feature, pfcSolid_ptr solid, pfcOutline3D_ptr globalOutline, double tolerance); std::vector GetFeatureAffectedSurfaces(pfcFeature_ptr feature, pfcSolid_ptr solid); bool IsSurfaceOnBoundary(pfcSurface_ptr surface, pfcSolid_ptr solid, pfcOutline3D_ptr globalOutline, double tolerance); bool CheckSurfaceBoundaryByBounds(pfcSurface_ptr surface, pfcOutline3D_ptr globalOutline, double tolerance); double CalculateDistanceToExternalSurface(pfcFeature_ptr feature, pfcSolid_ptr solid); // Enhanced assembly component occlusion analysis bool IsComponentOccludedByOthers( pfcFeature_ptr component, pfcOutline3D_ptr assembly_bbox, const std::vector>& all_components, double tolerance); double CalculateOcclusionRatio(pfcFeature_ptr target, pfcFeature_ptr occluder); bool HasInterferenceWith(pfcFeature_ptr comp1, pfcFeature_ptr comp2); // Estimate feature scale based on type and parameters double EstimateFeatureScale(pfcFeature_ptr feature); // 大模型优化方法 ShellAnalysisMode DetermineAnalysisMode(int feature_count); std::vector GetSamplingIndices(int total_features, ShellAnalysisMode mode); // 优化的估算方法 EstimatedReduction CalculateRealisticReduction( const std::vector& deletions, double original_volume, int total_features); // 辅助功能 std::string GetCurrentTimeString(); std::string GetCurrentTimeStringISO(); std::string GetFileSize(const std::string& filepath); int SafeCalculateAssemblyLevels(wfcWAssembly_ptr assembly); // 会话信息获取 SessionInfo GetSessionInfo(); // Volume calculation double GetComponentVolume(pfcSolid_ptr solid); // 字符串转换辅助函数 std::string XStringToString(const xstring& xstr); // 组件路径构建函数 std::string BuildComponentFullPath(wfcWComponentPath_ptr componentPath, const std::string& assemblyName); // 文件大小统计 std::string GetModelFileSize(pfcModel_ptr model); std::string CalculateAssemblyTotalSize(pfcModel_ptr model); double ParseMBFromSizeString(const std::string& size_str); // Component analysis helper methods std::string EvaluateDeletionSafety(const ComponentInfo& component); std::string GetComponentFileSize(wfcWComponentPath_ptr component_path); std::string GetModelTypeString(pfcModelType model_type); int CountChildComponents(wfcWComponentPath_ptr component_path); private: CreoManager(); // 需要自定义构造函数来设置配置 ~CreoManager() = default; CreoManager(const CreoManager&) = delete; CreoManager& operator=(const CreoManager&) = delete; // 辅助函数 xstring StringToXString(const std::string& str); std::pair ParseFilePath(const std::string& file_path); // 层级分析私有方法 (新SOTA算法) void AnalyzeAssemblyNode(wfcWAssembly_ptr assembly, int level, const std::string& parentName, const std::string& currentPath, HierarchyAnalysisResult& result, int target_level = -1); // 新增参数 ComponentInfo CreateComponentFromFeature(pfcComponentFeat_ptr compFeat, int level, const std::string& parentName, const std::string& currentPath, pfcModel_ptr preloadedModel = nullptr); pfcModel_ptr LoadComponentModel(pfcComponentFeat_ptr compFeat); // 薄壳化分析递归方法 void CollectAllComponentsForShellAnalysis(wfcWAssembly_ptr assembly, const std::string& parentPath, std::vector>& allComponents); // Shell Analysis Cache class ShellAnalysisCache { private: struct FeatureCacheEntry { double volume_impact; double surface_impact; double confidence; std::time_t timestamp; std::string model_version; // Added for cache validation int64_t model_modified_time; // Added for cache validation }; std::map cache; public: bool GetCachedImpact(const std::string& key, double& volume, double& surface, const std::string& current_version = "", int64_t current_modified_time = 0) { auto it = cache.find(key); if (it != cache.end()) { // Check both TTL and model state consistency bool ttl_valid = (std::time(nullptr) - it->second.timestamp < ShellAnalysisConstants::CACHE_TTL_SECONDS); bool version_valid = (current_version.empty() || it->second.model_version == current_version); bool time_valid = (current_modified_time == 0 || it->second.model_modified_time == current_modified_time); if (ttl_valid && version_valid && time_valid) { volume = it->second.volume_impact; surface = it->second.surface_impact; return true; } // Invalid cache entry, remove it cache.erase(it); } return false; } void SetCachedImpact(const std::string& key, double volume, double surface, const std::string& model_version = "", int64_t model_modified_time = 0) { FeatureCacheEntry entry; entry.volume_impact = volume; entry.surface_impact = surface; entry.timestamp = std::time(nullptr); entry.model_version = model_version; entry.model_modified_time = model_modified_time; cache[key] = entry; // Limit cache size if (cache.size() > ShellAnalysisConstants::MAX_CACHE_SIZE) { auto oldest = cache.begin(); for (auto it = cache.begin(); it != cache.end(); ++it) { if (it->second.timestamp < oldest->second.timestamp) { oldest = it; } } cache.erase(oldest); } } void ClearCache() { cache.clear(); } }; // Cache instance ShellAnalysisCache shell_analysis_cache; // 真实几何分析方法 bool AnalyzeFeatureGeometry(pfcFeature_ptr feature, pfcOutline3D_ptr globalOutline, double tolerance); // Multi-directional extreme value projection algorithm structures and functions struct Vector3D { double x, y, z; Vector3D() : x(0), y(0), z(0) {} Vector3D(double x_, double y_, double z_) : x(x_), y(y_), z(z_) {} Vector3D operator-(const Vector3D& other) const { return Vector3D(x - other.x, y - other.y, z - other.z); } Vector3D operator+(const Vector3D& other) const { return Vector3D(x + other.x, y + other.y, z + other.z); } Vector3D operator*(double scalar) const { return Vector3D(x * scalar, y * scalar, z * scalar); } double dot(const Vector3D& other) const { return x * other.x + y * other.y + z * other.z; } Vector3D cross(const Vector3D& other) const { return Vector3D( y * other.z - z * other.y, z * other.x - x * other.z, x * other.y - y * other.x ); } double length() const { return sqrt(x * x + y * y + z * z); } Vector3D normalize() const { double len = length(); if (len > 1e-10) { return Vector3D(x / len, y / len, z / len); } return Vector3D(0, 0, 1); } }; struct AABB { Vector3D minPoint, maxPoint; AABB() : minPoint(1e9, 1e9, 1e9), maxPoint(-1e9, -1e9, -1e9) {} AABB(const Vector3D& min_pt, const Vector3D& max_pt) : minPoint(min_pt), maxPoint(max_pt) {} void expand(const Vector3D& point) { if (point.x < minPoint.x) minPoint.x = point.x; if (point.y < minPoint.y) minPoint.y = point.y; if (point.z < minPoint.z) minPoint.z = point.z; if (point.x > maxPoint.x) maxPoint.x = point.x; if (point.y > maxPoint.y) maxPoint.y = point.y; if (point.z > maxPoint.z) maxPoint.z = point.z; } Vector3D diagonal() const { return maxPoint - minPoint; } double getDiagonalLength() const { return diagonal().length(); } // Get all 8 corners of AABB std::vector getCorners() const { std::vector corners; corners.reserve(8); for (int i = 0; i < 8; i++) { corners.push_back(Vector3D( (i & 1) ? maxPoint.x : minPoint.x, (i & 2) ? maxPoint.y : minPoint.y, (i & 4) ? maxPoint.z : minPoint.z )); } return corners; } }; // Forward declarations struct OBB; // 2D Screen Grid for visibility calculation struct ScreenGrid { struct Cell { double depth = std::numeric_limits::max(); int componentId = -1; }; Vector3D origin; // Grid origin point Vector3D uAxis, vAxis; // Orthonormal basis vectors double width, height; // Grid dimensions int gridSizeU, gridSizeV; std::vector> cells; ScreenGrid() : gridSizeU(0), gridSizeV(0), width(0), height(0) {} ScreenGrid(const AABB& sceneBounds, const Vector3D& viewDir, int gridSize = 96) { gridSizeU = gridSize; gridSizeV = gridSize; // Build orthonormal basis if (std::abs(viewDir.x) > 0.9) { uAxis = Vector3D(0, 1, 0).cross(viewDir).normalize(); } else { uAxis = Vector3D(1, 0, 0).cross(viewDir).normalize(); } vAxis = viewDir.cross(uAxis).normalize(); // Calculate grid bounds std::vector corners = sceneBounds.getCorners(); double minU = std::numeric_limits::max(); double maxU = std::numeric_limits::lowest(); double minV = std::numeric_limits::max(); double maxV = std::numeric_limits::lowest(); for (const auto& corner : corners) { double u = corner.dot(uAxis); double v = corner.dot(vAxis); minU = std::min(minU, u); maxU = std::max(maxU, u); minV = std::min(minV, v); maxV = std::max(maxV, v); } // Set origin and dimensions origin = Vector3D(minU, minV, 0); width = maxU - minU; height = maxV - minV; // Initialize cells cells.resize(gridSizeU, std::vector(gridSizeV)); } void updateCell(int u, int v, double depth, int id) { if (u >= 0 && u < gridSizeU && v >= 0 && v < gridSizeV) { if (depth < cells[u][v].depth) { cells[u][v].depth = depth; cells[u][v].componentId = id; } } } std::pair worldToGrid(const Vector3D& point) const { double u = point.dot(uAxis) - origin.x; double v = point.dot(vAxis) - origin.y; int gridU = static_cast((u / width) * gridSizeU); int gridV = static_cast((v / height) * gridSizeV); return {gridU, gridV}; } void projectAABB(const AABB& box, const Vector3D& viewDir, double minDepth, int componentId) { std::vector corners = box.getCorners(); // Find UV bounds of projection int minGridU = gridSizeU, maxGridU = -1; int minGridV = gridSizeV, maxGridV = -1; for (const auto& corner : corners) { std::pair gridPos = worldToGrid(corner); int u = gridPos.first; int v = gridPos.second; minGridU = std::min(minGridU, std::max(0, u)); maxGridU = std::max(maxGridU, std::min(gridSizeU - 1, u)); minGridV = std::min(minGridV, std::max(0, v)); maxGridV = std::max(maxGridV, std::min(gridSizeV - 1, v)); } // Update cells in bounding rectangle for (int u = minGridU; u <= maxGridU; u++) { for (int v = minGridV; v <= maxGridV; v++) { updateCell(u, v, minDepth, componentId); } } } void projectOBB(const OBB& box, const Vector3D& viewDir, double minDepth, int componentId) { std::vector corners = box.getCorners(); // Find UV bounds of projection int minGridU = gridSizeU, maxGridU = -1; int minGridV = gridSizeV, maxGridV = -1; for (const auto& corner : corners) { std::pair gridPos = worldToGrid(corner); int u = gridPos.first; int v = gridPos.second; minGridU = std::min(minGridU, std::max(0, u)); maxGridU = std::max(maxGridU, std::min(gridSizeU - 1, u)); minGridV = std::min(minGridV, std::max(0, v)); maxGridV = std::max(maxGridV, std::min(gridSizeV - 1, v)); } // Update cells in bounding rectangle for (int u = minGridU; u <= maxGridU; u++) { for (int v = minGridV; v <= maxGridV; v++) { updateCell(u, v, minDepth, componentId); } } } std::unordered_map getVisibilityCount() const { std::unordered_map counts; for (const auto& row : cells) { for (const auto& cell : row) { if (cell.componentId >= 0) { counts[cell.componentId]++; } } } return counts; } }; // Oriented Bounding Box for enhanced precision struct OBB { Vector3D center; // Center point in world space Vector3D halfExtents; // Half extents in local space Vector3D axes[3]; // Three orthogonal axes in world space OBB() : center(0, 0, 0), halfExtents(0, 0, 0) { axes[0] = Vector3D(1, 0, 0); axes[1] = Vector3D(0, 1, 0); axes[2] = Vector3D(0, 0, 1); } // Calculate support point projection for OBB in given direction double getSupport(const Vector3D& direction) const { // Transform world direction to OBB local space Vector3D localDir( direction.dot(axes[0]), direction.dot(axes[1]), direction.dot(axes[2]) ); // Calculate local space support point Vector3D support; support.x = (localDir.x >= 0) ? halfExtents.x : -halfExtents.x; support.y = (localDir.y >= 0) ? halfExtents.y : -halfExtents.y; support.z = (localDir.z >= 0) ? halfExtents.z : -halfExtents.z; // Transform back to world space and calculate projection Vector3D worldSupport = center + axes[0] * support.x + axes[1] * support.y + axes[2] * support.z; return worldSupport.dot(direction); } // Get all 8 corners of the OBB std::vector getCorners() const { std::vector corners; corners.reserve(8); for (int i = 0; i < 8; i++) { Vector3D corner = center; corner = corner + axes[0] * ((i & 1) ? halfExtents.x : -halfExtents.x); corner = corner + axes[1] * ((i & 2) ? halfExtents.y : -halfExtents.y); corner = corner + axes[2] * ((i & 4) ? halfExtents.z : -halfExtents.z); corners.push_back(corner); } return corners; } }; struct ComponentItem { pfcComponentFeat_ptr component; pfcSolid_ptr solid; pfcComponentPath_ptr path; AABB worldAABB; // Fast rough filtering OBB worldOBB; // Precise oriented bounding box int featureId; std::string name; }; // Projection analysis result data structure struct ProjectionAnalysisData { std::unordered_map visibilityVotes; // component ID -> visibility count std::unordered_set outerComponentIds; // outer component IDs std::vector components; // all components with AABB data AABB globalAABB; // global assembly bounding box std::unordered_map visibilityRatios; // component ID -> continuous visibility ratio // OBB optimization statistics int obb_usage_count = 0; int aabb_usage_count = 0; double obb_usage_percentage = 0.0; }; // Component classification based on naming patterns and geometry class ComponentClassifier { public: // Structure for specific internal models struct SpecificInternalModel { std::string name; // Model name (e.g., "12v4000g03_herhang.prt") std::string pathSegment; // Path segment for validation (optional) }; // Check if component name indicates a fastener static bool IsFastener(const std::string& name); // Check if component name indicates internal structure static bool IsInternalStructure(const std::string& name); // Check if component name indicates external shell static bool IsExternalShell(const std::string& name); // Check if component is likely internal based on geometry static bool IsLikelyInternal(const AABB& compAABB, const AABB& globalAABB); // Check if component is elongated/thin (benefits from OBB) static bool IsElongatedPart(const std::string& name); // Check if component is a specific internal model static bool IsSpecificInternalModel(const std::string& name, const std::string& path); // List of specific models to be marked as internal static std::vector specificInternalModels; private: static bool MatchesPattern(const std::string& text, const std::vector& patterns); }; // Multi-directional projection algorithm functions std::pair CalculateAABBProjectionRange(const AABB& aabb, const Vector3D& direction); std::pair CalculateOBBProjectionRange(const OBB& obb, const Vector3D& direction); ProjectionAnalysisData PerformMultiDirectionalProjectionAnalysis(pfcAssembly_ptr assembly); std::vector CollectAllComponents(pfcAssembly_ptr assembly); std::vector SampleDirections(int count = 96); AABB TransformAABB(const AABB& localAABB, pfcTransform3D_ptr transform); pfcTransform3D_ptr GetComponentWorldTransform(pfcComponentPath_ptr path); double CalculateProjectionSupport(const AABB& aabb, const Vector3D& direction); Vector3D PfcPointToVector3D(pfcPoint3D_ptr point); AABB PfcOutlineToAABB(pfcOutline3D_ptr outline); // OBB-related functions for enhanced precision OBB ExtractOBBFromTransform(const AABB& localAABB, pfcTransform3D_ptr transform); OBB ComputePCABasedOBB(pfcSolid_ptr solid, pfcTransform3D_ptr transform); std::vector ExtractSolidVertices(pfcSolid_ptr solid, int maxVertices = 1000); OBB ComputeOBBFromVertices(const std::vector& vertices); std::vector ComputePrincipalAxes(const std::vector& vertices); double CalculateOBBProjectionSupport(const OBB& obb, const Vector3D& direction); double CalculateOBBThickness(const OBB& obb, const Vector3D& direction); bool ShouldUseOBB(const ComponentItem& comp); // Ray-based verification for shell analysis bool IsComponentBlockedFromCenter(const Vector3D& globalCenter, const ComponentItem& component, const std::vector& allComponents); };