From 5a1d0386a9e074e31825d4be0fd4142f1deb916d Mon Sep 17 00:00:00 2001 From: sladro Date: Fri, 19 Sep 2025 21:28:54 +0800 Subject: [PATCH] feat: implement same-path component visibility sharing and assembly filtering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- CreoManager.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/CreoManager.cpp b/CreoManager.cpp index 1d31e96..8f089e0 100644 --- a/CreoManager.cpp +++ b/CreoManager.cpp @@ -2668,6 +2668,12 @@ std::vector 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 featureIdToPath; + std::unordered_map 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 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; }