feat: implement same-path component visibility sharing and assembly filtering

- Add path-based visibility logic: same-path components share visibility
- Filter out assembly (.asm) components during data collection phase
- Fix duplicate voting issue with proper post-processing approach
- Optimize performance by excluding assemblies from analysis pipeline

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
sladro 2025-09-19 21:28:54 +08:00
parent 1a561f0b5c
commit 5a1d0386a9

View File

@ -2668,6 +2668,12 @@ std::vector<CreoManager::ComponentItem> CreoManager::CollectAllComponents(pfcAss
compName = "COMPONENT_" + std::to_string(i + 1);
}
// Skip assembly components - only analyze parts
if (compName.find(".asm") != std::string::npos ||
compName.find(".ASM") != std::string::npos) {
continue;
}
// Get stable feature ID from component path - use the leaf component ID
int stableFeatureId = -1;
xintsequence_ptr componentIds = wPath->GetComponentIds();
@ -2791,6 +2797,45 @@ CreoManager::ProjectionAnalysisData CreoManager::PerformMultiDirectionalProjecti
result.visibilityVotes.reserve(result.components.size());
// Create featureId to path mapping for visibility logic
std::unordered_map<int, std::string> featureIdToPath;
std::unordered_map<int, std::string> featureIdToName;
// Build path mapping for each component
wfcWAssembly_ptr wAssembly = wfcWAssembly::cast(assembly);
if (wAssembly) {
wfcWComponentPaths_ptr componentPaths = wAssembly->ListDisplayedComponents();
if (componentPaths) {
SessionInfo sessionInfo = GetSessionInfo();
std::string assemblyName = "";
if (sessionInfo.is_valid) {
pfcModel_ptr currentModel = sessionInfo.session->GetCurrentModel();
if (currentModel) {
xstring assemblyXStr = currentModel->GetFileName();
assemblyName = XStringToString(assemblyXStr);
}
}
for (int i = 0; i < componentPaths->getarraysize(); ++i) {
wfcWComponentPath_ptr wPath = componentPaths->get(i);
if (wPath) {
// Get feature ID
xintsequence_ptr componentIds = wPath->GetComponentIds();
if (componentIds && componentIds->getarraysize() > 0) {
int featureId = componentIds->get(componentIds->getarraysize() - 1);
// Build full path for this component
std::string fullPath = BuildComponentFullPath(wPath, assemblyName);
featureIdToPath[featureId] = fullPath;
}
}
}
}
}
for (const ComponentItem& comp : result.components) {
featureIdToName[comp.featureId] = comp.name;
}
// Step 4: For each direction, determine visible components using occlusion detection
for (const Vector3D& direction : directions) {
// Structure to hold projection data
@ -2850,6 +2895,24 @@ CreoManager::ProjectionAnalysisData CreoManager::PerformMultiDirectionalProjecti
}
}
// Step 6: Post-process - if any component with a path is visible, mark all same-path components as visible
std::set<std::string> visiblePaths;
for (int visibleFeatureId : result.outerComponentIds) {
auto pathIter = featureIdToPath.find(visibleFeatureId);
if (pathIter != featureIdToPath.end()) {
visiblePaths.insert(pathIter->second);
}
}
// Add all components with visible paths to outer component set
for (const auto& pathEntry : featureIdToPath) {
int featureId = pathEntry.first;
const std::string& path = pathEntry.second;
if (visiblePaths.find(path) != visiblePaths.end()) {
result.outerComponentIds.insert(featureId);
}
}
return result;
}