- Add depth window approach instead of single extreme value selection - Implement voting mechanism: components need visibility in 8%+ directions - Multi-level confidence based on visibility ratio (25%/8% thresholds) - Calculate adaptive depth window: max(0.2% diagonal, 15% median thickness) - Add top-K fallback to ensure minimum visible components - Fix compilation errors: add unordered_map header, fix C++17 syntax This reduces over-aggressive deletion from 90% to more reasonable levels by properly identifying partially visible components in second/third layers. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
591 lines
21 KiB
C++
591 lines
21 KiB
C++
#pragma once
|
||
|
||
// 基础OTK头文件 - 确保正确的包含顺序
|
||
#include <pfcGlobal.h>
|
||
#include <pfcSession.h>
|
||
#include <wfcSession.h>
|
||
#include <wfcGlobal.h>
|
||
#include <pfcModel.h>
|
||
#include <pfcExceptions.h>
|
||
#include <pfcExport.h>
|
||
#include <pfcFeature.h>
|
||
#include <pfcComponentFeat.h>
|
||
#include <pfcFeature_s.h>
|
||
#include <pfcSolid.h>
|
||
#include <wfcSolid.h>
|
||
#include <wfcSolidInstructions.h>
|
||
#include <pfcInterference.h>
|
||
#include <pfcSelect.h>
|
||
#include <pfcGeometry.h>
|
||
#include <pfcAssembly.h>
|
||
#include <string>
|
||
#include <vector>
|
||
#include <map>
|
||
#include <set>
|
||
#include <unordered_set>
|
||
#include <algorithm>
|
||
#include <cmath>
|
||
|
||
// 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<std::string, std::string> analysis_options;
|
||
};
|
||
|
||
// 删除建议结构
|
||
struct DeletionRecommendation {
|
||
std::string component_id;
|
||
std::string component_name;
|
||
int level;
|
||
std::string reason;
|
||
std::vector<std::string> risk_factors;
|
||
double confidence;
|
||
};
|
||
|
||
// 层级分析结果结构
|
||
struct HierarchyAnalysisResult {
|
||
bool success = false;
|
||
std::string message;
|
||
std::string project_name;
|
||
int total_levels;
|
||
int total_components;
|
||
std::vector<std::vector<ComponentInfo>> hierarchy;
|
||
std::vector<DeletionRecommendation> safe_deletions;
|
||
std::vector<DeletionRecommendation> 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<int, std::vector<std::string>> deleted_components;
|
||
int total_deleted;
|
||
int successful;
|
||
int failed;
|
||
std::string error_message;
|
||
};
|
||
|
||
HierarchyDeleteResult DeleteHierarchyComponents(const std::string& project_name, 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
|
||
};
|
||
|
||
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<std::string, std::string> 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;
|
||
bool is_deletable = false;
|
||
};
|
||
|
||
struct ShellAnalysisResult {
|
||
bool success = false;
|
||
std::vector<FeatureDeletion> safe_deletions;
|
||
std::vector<FeatureDeletion> suggested_deletions;
|
||
std::vector<FeatureDeletion> preserve_list;
|
||
EstimatedReduction estimated_reduction;
|
||
ShellAnalysisParameters analysis_parameters;
|
||
std::string error_message;
|
||
|
||
// Enhanced fields for new algorithm
|
||
std::vector<ShellAnalysisItem> 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;
|
||
};
|
||
|
||
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<double> CalculateBatchFeatureVolumeImpacts(
|
||
const std::vector<pfcFeature_ptr>& features,
|
||
pfcSolid_ptr solid,
|
||
int batch_size = 10);
|
||
|
||
// LOO (Leave-One-Out) attribution for accurate feature impact calculation
|
||
std::vector<double> CalculateLOOAttribution(
|
||
const std::vector<pfcFeature_ptr>& 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<pfcSurface_ptr> 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<std::pair<pfcFeature_ptr, std::string>>& 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<int> GetSamplingIndices(int total_features, ShellAnalysisMode mode);
|
||
|
||
// 优化的估算方法
|
||
EstimatedReduction CalculateRealisticReduction(
|
||
const std::vector<FeatureDeletion>& 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();
|
||
|
||
// 字符串转换辅助函数
|
||
std::string XStringToString(const xstring& xstr);
|
||
|
||
// 文件大小统计
|
||
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<std::string, std::string> 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<std::pair<pfcFeature_ptr, std::string>>& 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<std::string, FeatureCacheEntry> 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);
|
||
}
|
||
|
||
double dot(const Vector3D& other) const {
|
||
return x * other.x + y * other.y + z * other.z;
|
||
}
|
||
|
||
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();
|
||
}
|
||
};
|
||
|
||
struct ComponentItem {
|
||
pfcComponentFeat_ptr component;
|
||
pfcSolid_ptr solid;
|
||
pfcComponentPath_ptr path;
|
||
AABB worldAABB;
|
||
int featureId;
|
||
std::string name;
|
||
};
|
||
|
||
// Multi-directional projection algorithm functions
|
||
std::unordered_set<int> PerformMultiDirectionalProjectionAnalysis(pfcAssembly_ptr assembly);
|
||
std::vector<ComponentItem> CollectAllComponents(pfcAssembly_ptr assembly);
|
||
std::vector<Vector3D> 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);
|
||
};
|