fix: improve shell analysis accuracy with depth window and voting mechanism
- 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>
This commit is contained in:
parent
1003178e17
commit
0bf81ee8d4
358
CreoManager.cpp
358
CreoManager.cpp
@ -30,8 +30,10 @@
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
#include <cstdlib>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
@ -1539,6 +1541,72 @@ CreoManager::ShellAnalysisResult CreoManager::AnalyzeShellFeaturesEnhanced(const
|
||||
// Execute multi-directional extreme value projection algorithm
|
||||
std::unordered_set<int> outerComponentIds = PerformMultiDirectionalProjectionAnalysis(assembly);
|
||||
|
||||
// Also need visibility votes for confidence mapping
|
||||
// Re-run the voting analysis to get detailed visibility scores
|
||||
std::unordered_map<int, int> visibilityVotes;
|
||||
const int numDirections = 96;
|
||||
std::vector<Vector3D> directions = SampleDirections(numDirections);
|
||||
|
||||
// Collect all components for visibility analysis
|
||||
std::vector<ComponentItem> allComponents = CollectAllComponents(assembly);
|
||||
AABB globalAABB;
|
||||
for (const ComponentItem& comp : allComponents) {
|
||||
globalAABB.expand(comp.worldAABB.minPoint);
|
||||
globalAABB.expand(comp.worldAABB.maxPoint);
|
||||
}
|
||||
|
||||
// Calculate visibility votes for each component
|
||||
for (const Vector3D& direction : directions) {
|
||||
struct ProjectionData {
|
||||
double support;
|
||||
double thickness;
|
||||
int featureId;
|
||||
};
|
||||
|
||||
std::vector<ProjectionData> projections;
|
||||
for (const ComponentItem& comp : allComponents) {
|
||||
double support = CalculateProjectionSupport(comp.worldAABB, direction);
|
||||
Vector3D minSupport, maxSupport;
|
||||
minSupport.x = (direction.x < 0) ? comp.worldAABB.maxPoint.x : comp.worldAABB.minPoint.x;
|
||||
minSupport.y = (direction.y < 0) ? comp.worldAABB.maxPoint.y : comp.worldAABB.minPoint.y;
|
||||
minSupport.z = (direction.z < 0) ? comp.worldAABB.maxPoint.z : comp.worldAABB.minPoint.z;
|
||||
maxSupport.x = (direction.x >= 0) ? comp.worldAABB.maxPoint.x : comp.worldAABB.minPoint.x;
|
||||
maxSupport.y = (direction.y >= 0) ? comp.worldAABB.maxPoint.y : comp.worldAABB.minPoint.y;
|
||||
maxSupport.z = (direction.z >= 0) ? comp.worldAABB.maxPoint.z : comp.worldAABB.minPoint.z;
|
||||
double thickness = std::abs((maxSupport - minSupport).dot(direction));
|
||||
projections.push_back({support, thickness, comp.featureId});
|
||||
}
|
||||
|
||||
std::sort(projections.begin(), projections.end(),
|
||||
[](const ProjectionData& a, const ProjectionData& b) {
|
||||
return a.support > b.support;
|
||||
});
|
||||
|
||||
if (!projections.empty()) {
|
||||
double bestSupport = projections.front().support;
|
||||
std::vector<double> thicknesses;
|
||||
for (const auto& p : projections) thicknesses.push_back(p.thickness);
|
||||
std::nth_element(thicknesses.begin(), thicknesses.begin() + thicknesses.size() / 2, thicknesses.end());
|
||||
double medianThickness = thicknesses[thicknesses.size() / 2];
|
||||
|
||||
double assemblyDiagonal = globalAABB.getDiagonalLength();
|
||||
double absoluteWindow = std::max(1e-6, 0.002 * assemblyDiagonal);
|
||||
double relativeWindow = 0.15 * medianThickness;
|
||||
double depthWindow = std::max(absoluteWindow, relativeWindow);
|
||||
int topK = std::min<int>(12, std::max<int>(3, (int)std::sqrt(allComponents.size())));
|
||||
|
||||
int rank = 0;
|
||||
for (const auto& proj : projections) {
|
||||
if ((proj.support >= bestSupport - depthWindow) || (rank < topK)) {
|
||||
visibilityVotes[proj.featureId]++;
|
||||
rank++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get all components using the same method as CollectAllComponents for ID consistency
|
||||
wfcWAssembly_ptr wAssembly = wfcWAssembly::cast(assembly);
|
||||
if (!wAssembly) {
|
||||
@ -1555,30 +1623,7 @@ CreoManager::ShellAnalysisResult CreoManager::AnalyzeShellFeaturesEnhanced(const
|
||||
int total_components = componentPaths->getarraysize();
|
||||
result.total_features_analyzed = total_components;
|
||||
|
||||
// Build feature ID map first (same approach as CollectAllComponents)
|
||||
std::map<std::string, int> modelNameToFeatureId;
|
||||
try {
|
||||
pfcFeatures_ptr features = assembly->ListFeaturesByType(xfalse, pfcFEATTYPE_COMPONENT);
|
||||
if (features) {
|
||||
for (int j = 0; j < features->getarraysize(); j++) {
|
||||
pfcFeature_ptr feature = features->get(j);
|
||||
if (!feature) continue;
|
||||
|
||||
pfcComponentFeat_ptr compFeat = pfcComponentFeat::cast(feature);
|
||||
if (!compFeat) continue;
|
||||
|
||||
pfcModelDescriptor_ptr modelDesc = compFeat->GetModelDescr();
|
||||
if (!modelDesc) continue;
|
||||
|
||||
std::string modelName = XStringToString(modelDesc->GetFileName());
|
||||
if (!modelName.empty()) {
|
||||
modelNameToFeatureId[modelName] = feature->GetId();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
// Continue with fallback approach if feature listing fails
|
||||
}
|
||||
// No need for feature ID map - we'll use component IDs directly from paths
|
||||
|
||||
// Build analysis result from projection analysis
|
||||
for (int i = 0; i < total_components; i++) {
|
||||
@ -1605,18 +1650,15 @@ CreoManager::ShellAnalysisResult CreoManager::AnalyzeShellFeaturesEnhanced(const
|
||||
comp_name = "COMPONENT_" + std::to_string(i + 1);
|
||||
}
|
||||
|
||||
// Get stable feature ID from map or use fallback
|
||||
// Get stable feature ID from component path - use the leaf component ID
|
||||
int stableFeatureId = -1;
|
||||
if (modelNameToFeatureId.find(comp_name) != modelNameToFeatureId.end()) {
|
||||
stableFeatureId = modelNameToFeatureId[comp_name];
|
||||
xintsequence_ptr componentIds = wPath->GetComponentIds();
|
||||
if (componentIds && componentIds->getarraysize() > 0) {
|
||||
// Use the last ID in the path which represents the leaf component
|
||||
stableFeatureId = componentIds->get(componentIds->getarraysize() - 1);
|
||||
} else {
|
||||
// Fallback: use component path IDs
|
||||
xintsequence_ptr componentIds = wPath->GetComponentIds();
|
||||
if (componentIds && componentIds->getarraysize() > 0) {
|
||||
stableFeatureId = componentIds->get(componentIds->getarraysize() - 1);
|
||||
} else {
|
||||
stableFeatureId = i; // Last resort: use index
|
||||
}
|
||||
// Should not happen, but use index as last resort
|
||||
stableFeatureId = i;
|
||||
}
|
||||
|
||||
// Create analysis item
|
||||
@ -1625,23 +1667,40 @@ CreoManager::ShellAnalysisResult CreoManager::AnalyzeShellFeaturesEnhanced(const
|
||||
item.type = "COMPONENT";
|
||||
item.feature_id = stableFeatureId; // Use stable feature ID
|
||||
|
||||
// Determine if this component is on outer surface based on projection analysis
|
||||
bool is_outer_component = (outerComponentIds.find(item.feature_id) != outerComponentIds.end());
|
||||
// Calculate visibility ratio for this component
|
||||
double visibilityRatio = 0.0;
|
||||
auto votesIter = visibilityVotes.find(item.feature_id);
|
||||
if (votesIter != visibilityVotes.end()) {
|
||||
visibilityRatio = (double)votesIter->second / numDirections;
|
||||
}
|
||||
|
||||
if (is_outer_component) {
|
||||
// Outer surface component - low deletion confidence
|
||||
item.confidence = 15.0;
|
||||
// Determine confidence based on visibility ratio
|
||||
if (visibilityRatio >= 0.25) {
|
||||
// Highly visible component - clearly on outer surface
|
||||
item.confidence = 0.1; // Very low deletion confidence
|
||||
item.recommendation = "KEEP";
|
||||
item.reason = "Component on assembly outer surface (multi-directional projection analysis)";
|
||||
item.reason = "Component highly visible from multiple directions (visibility: " +
|
||||
std::to_string((int)(visibilityRatio * 100)) + "%)";
|
||||
result.shell_features_count++;
|
||||
} else if (visibilityRatio >= 0.08) {
|
||||
// Partially visible component - likely on outer surface or important structure
|
||||
item.confidence = 0.4; // Medium deletion confidence
|
||||
item.recommendation = "REVIEW";
|
||||
item.reason = "Component partially visible (visibility: " +
|
||||
std::to_string((int)(visibilityRatio * 100)) + "%)";
|
||||
result.shell_features_count++;
|
||||
} else {
|
||||
// Internal component - high deletion confidence
|
||||
item.confidence = 85.0;
|
||||
// Internal component - mostly not visible
|
||||
item.confidence = 0.85; // High deletion confidence
|
||||
item.recommendation = "DELETE";
|
||||
item.reason = "Internal component not visible from any direction (multi-directional projection analysis)";
|
||||
item.reason = "Internal component with minimal visibility (visibility: " +
|
||||
std::to_string((int)(visibilityRatio * 100)) + "%)";
|
||||
result.internal_features_count++;
|
||||
}
|
||||
|
||||
// Check if it was identified as outer component by the main algorithm
|
||||
bool is_outer_component = (outerComponentIds.find(item.feature_id) != outerComponentIds.end());
|
||||
|
||||
// Apply user preferences
|
||||
if (request.preserve_external_surfaces && is_outer_component) {
|
||||
item.confidence = 0.0; // Force keep
|
||||
@ -1667,6 +1726,58 @@ CreoManager::ShellAnalysisResult CreoManager::AnalyzeShellFeaturesEnhanced(const
|
||||
return a.confidence > b.confidence;
|
||||
});
|
||||
|
||||
// Convert features to categorized deletion lists
|
||||
for (const auto& item : result.features) {
|
||||
FeatureDeletion deletion;
|
||||
deletion.id = item.feature_id;
|
||||
deletion.name = item.name;
|
||||
deletion.type = item.type;
|
||||
deletion.reason = item.reason;
|
||||
deletion.confidence = item.confidence;
|
||||
deletion.volume_reduction = 0.0; // Not calculated in projection analysis
|
||||
deletion.part_file = ""; // Component name is already in 'name'
|
||||
deletion.part_path = ""; // Not available in current analysis
|
||||
deletion.component_type = "COMPONENT";
|
||||
|
||||
if (item.confidence >= 0.8) {
|
||||
// Safe deletion - high confidence internal components
|
||||
result.safe_deletions.push_back(deletion);
|
||||
} else if (item.confidence >= 0.5) {
|
||||
// Suggested deletion - medium confidence components
|
||||
result.suggested_deletions.push_back(deletion);
|
||||
} else {
|
||||
// Preserve - low confidence or outer surface components
|
||||
result.preserve_list.push_back(deletion);
|
||||
}
|
||||
}
|
||||
|
||||
// Update statistics fields
|
||||
result.analysis_parameters.total_features = result.total_features_analyzed;
|
||||
result.analysis_parameters.deletable_features = result.safe_deletions.size() + result.suggested_deletions.size();
|
||||
result.analysis_parameters.preserved_features = result.preserve_list.size();
|
||||
result.analysis_parameters.surface_count = result.total_features_analyzed; // All components analyzed
|
||||
result.analysis_parameters.shell_surfaces = result.shell_features_count; // Outer surface components
|
||||
result.analysis_parameters.internal_surfaces = result.internal_features_count; // Internal components
|
||||
|
||||
// Calculate estimated reduction (simplified for projection analysis)
|
||||
if (result.total_features_analyzed > 0) {
|
||||
double safe_reduction_pct = (double)result.safe_deletions.size() / result.total_features_analyzed * 100.0;
|
||||
double suggested_reduction_pct = (double)result.suggested_deletions.size() / result.total_features_analyzed * 100.0;
|
||||
|
||||
std::ostringstream volume_str, filesize_str, performance_str;
|
||||
volume_str << std::fixed << std::setprecision(1) << (safe_reduction_pct + suggested_reduction_pct * 0.5) << "%";
|
||||
filesize_str << std::fixed << std::setprecision(1) << (safe_reduction_pct * 0.7 + suggested_reduction_pct * 0.3) << "%";
|
||||
performance_str << std::fixed << std::setprecision(0) << (safe_reduction_pct * 1.5 + suggested_reduction_pct * 0.8) << "%";
|
||||
|
||||
result.estimated_reduction.volume_reduction = volume_str.str();
|
||||
result.estimated_reduction.file_size_reduction = filesize_str.str();
|
||||
result.estimated_reduction.performance_improvement = performance_str.str();
|
||||
} else {
|
||||
result.estimated_reduction.volume_reduction = "0%";
|
||||
result.estimated_reduction.file_size_reduction = "0%";
|
||||
result.estimated_reduction.performance_improvement = "0%";
|
||||
}
|
||||
|
||||
// Calculate statistics
|
||||
result.deletion_percentage = (result.total_features_analyzed > 0) ?
|
||||
(double(result.total_deletable) / result.total_features_analyzed * 100.0) : 0.0;
|
||||
@ -2459,35 +2570,7 @@ std::vector<CreoManager::ComponentItem> CreoManager::CollectAllComponents(pfcAss
|
||||
if (!assembly) return components;
|
||||
|
||||
try {
|
||||
// Step 1: Build a map of all component features and their IDs
|
||||
std::map<std::string, int> modelNameToFeatureId;
|
||||
std::map<std::string, pfcComponentFeat_ptr> modelNameToCompFeat;
|
||||
|
||||
try {
|
||||
pfcFeatures_ptr features = assembly->ListFeaturesByType(xfalse, pfcFEATTYPE_COMPONENT);
|
||||
if (features) {
|
||||
for (int i = 0; i < features->getarraysize(); i++) {
|
||||
pfcFeature_ptr feature = features->get(i);
|
||||
if (!feature) continue;
|
||||
|
||||
pfcComponentFeat_ptr compFeat = pfcComponentFeat::cast(feature);
|
||||
if (!compFeat) continue;
|
||||
|
||||
// Get model descriptor to get the model name
|
||||
pfcModelDescriptor_ptr modelDesc = compFeat->GetModelDescr();
|
||||
if (!modelDesc) continue;
|
||||
|
||||
std::string modelName = XStringToString(modelDesc->GetFileName());
|
||||
if (!modelName.empty()) {
|
||||
int featureId = feature->GetId();
|
||||
modelNameToFeatureId[modelName] = featureId;
|
||||
modelNameToCompFeat[modelName] = compFeat;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
// If we can't get features, fall back to using component IDs
|
||||
}
|
||||
// We don't need feature mapping - will use component IDs directly from paths
|
||||
|
||||
// Step 2: Use wfcWAssembly to get component paths with transforms
|
||||
wfcWAssembly_ptr wAssembly = wfcWAssembly::cast(assembly);
|
||||
@ -2521,22 +2604,15 @@ std::vector<CreoManager::ComponentItem> CreoManager::CollectAllComponents(pfcAss
|
||||
compName = "COMPONENT_" + std::to_string(i + 1);
|
||||
}
|
||||
|
||||
// Get stable feature ID from our map, or use component path ID as fallback
|
||||
// Get stable feature ID from component path - use the leaf component ID
|
||||
int stableFeatureId = -1;
|
||||
pfcComponentFeat_ptr compFeat = nullptr;
|
||||
|
||||
if (modelNameToFeatureId.find(compName) != modelNameToFeatureId.end()) {
|
||||
// Found in our feature map - use the stable feature ID
|
||||
stableFeatureId = modelNameToFeatureId[compName];
|
||||
compFeat = modelNameToCompFeat[compName];
|
||||
xintsequence_ptr componentIds = wPath->GetComponentIds();
|
||||
if (componentIds && componentIds->getarraysize() > 0) {
|
||||
// Use the last ID in the path which represents the leaf component
|
||||
stableFeatureId = componentIds->get(componentIds->getarraysize() - 1);
|
||||
} else {
|
||||
// Fallback: use the last component ID from the path
|
||||
xintsequence_ptr componentIds = wPath->GetComponentIds();
|
||||
if (componentIds && componentIds->getarraysize() > 0) {
|
||||
stableFeatureId = componentIds->get(componentIds->getarraysize() - 1);
|
||||
} else {
|
||||
stableFeatureId = i; // Last resort: use index
|
||||
}
|
||||
// Should not happen, but use index as last resort
|
||||
stableFeatureId = i;
|
||||
}
|
||||
|
||||
// Get local AABB
|
||||
@ -2557,11 +2633,11 @@ std::vector<CreoManager::ComponentItem> CreoManager::CollectAllComponents(pfcAss
|
||||
|
||||
// Create component item with complete information
|
||||
ComponentItem item;
|
||||
item.component = compFeat; // May be nullptr if not found in map
|
||||
item.component = nullptr; // We don't have pfcComponentFeat directly
|
||||
item.solid = compSolid;
|
||||
item.path = nullptr; // We have wfcWComponentPath, different type
|
||||
item.worldAABB = worldAABB;
|
||||
item.featureId = stableFeatureId; // Use stable feature ID when available
|
||||
item.featureId = stableFeatureId; // Use stable feature ID from component path
|
||||
item.name = compName;
|
||||
|
||||
components.push_back(item);
|
||||
@ -2581,14 +2657,14 @@ std::vector<CreoManager::ComponentItem> CreoManager::CollectAllComponents(pfcAss
|
||||
return components;
|
||||
}
|
||||
|
||||
// Main multi-directional extreme value projection analysis
|
||||
// Main multi-directional extreme value projection analysis with depth window and voting
|
||||
std::unordered_set<int> CreoManager::PerformMultiDirectionalProjectionAnalysis(pfcAssembly_ptr assembly) {
|
||||
std::unordered_set<int> outerComponentIds;
|
||||
|
||||
if (!assembly) return outerComponentIds;
|
||||
|
||||
try {
|
||||
// Step 1: Collect all components recursively
|
||||
// Step 1: Collect all components
|
||||
std::vector<ComponentItem> components = CollectAllComponents(assembly);
|
||||
if (components.empty()) return outerComponentIds;
|
||||
|
||||
@ -2599,40 +2675,100 @@ std::unordered_set<int> CreoManager::PerformMultiDirectionalProjectionAnalysis(p
|
||||
globalAABB.expand(comp.worldAABB.maxPoint);
|
||||
}
|
||||
|
||||
// Step 3: Calculate tolerance based on assembly size
|
||||
double assemblyDiagonal = globalAABB.getDiagonalLength();
|
||||
double tolerance = std::max(1e-6, assemblyDiagonal * 0.001); // 0.1% of assembly diagonal for better precision
|
||||
// Step 3: Sample directions (96 directions for good coverage)
|
||||
const int numDirections = 96;
|
||||
std::vector<Vector3D> directions = SampleDirections(numDirections);
|
||||
|
||||
// Step 4: Sample directions (96 directions for good coverage)
|
||||
std::vector<Vector3D> directions = SampleDirections(96);
|
||||
// Voting map: component ID -> number of directions where it's visible
|
||||
std::unordered_map<int, int> visibilityVotes;
|
||||
visibilityVotes.reserve(components.size());
|
||||
|
||||
// Step 5: For each direction, find extreme value components
|
||||
// Step 4: For each direction, determine visible components using depth window
|
||||
for (const Vector3D& direction : directions) {
|
||||
double maxProjection = -std::numeric_limits<double>::infinity();
|
||||
std::vector<int> candidateIds;
|
||||
// Structure to hold projection data
|
||||
struct ProjectionData {
|
||||
double support; // Projection support value
|
||||
double thickness; // Component thickness in this direction
|
||||
int featureId;
|
||||
};
|
||||
|
||||
// Find maximum projection in this direction
|
||||
std::vector<ProjectionData> projections;
|
||||
projections.reserve(components.size());
|
||||
|
||||
// Calculate projections and thickness for all components
|
||||
for (const ComponentItem& comp : components) {
|
||||
double projection = CalculateProjectionSupport(comp.worldAABB, direction);
|
||||
if (projection > maxProjection) {
|
||||
maxProjection = projection;
|
||||
candidateIds.clear();
|
||||
candidateIds.push_back(comp.featureId);
|
||||
} else if (abs(projection - maxProjection) <= tolerance) {
|
||||
// Within tolerance of maximum - also consider as frontmost
|
||||
candidateIds.push_back(comp.featureId);
|
||||
}
|
||||
double support = CalculateProjectionSupport(comp.worldAABB, direction);
|
||||
|
||||
// Calculate thickness as component extent in this direction
|
||||
Vector3D minSupport, maxSupport;
|
||||
minSupport.x = (direction.x < 0) ? comp.worldAABB.maxPoint.x : comp.worldAABB.minPoint.x;
|
||||
minSupport.y = (direction.y < 0) ? comp.worldAABB.maxPoint.y : comp.worldAABB.minPoint.y;
|
||||
minSupport.z = (direction.z < 0) ? comp.worldAABB.maxPoint.z : comp.worldAABB.minPoint.z;
|
||||
maxSupport.x = (direction.x >= 0) ? comp.worldAABB.maxPoint.x : comp.worldAABB.minPoint.x;
|
||||
maxSupport.y = (direction.y >= 0) ? comp.worldAABB.maxPoint.y : comp.worldAABB.minPoint.y;
|
||||
maxSupport.z = (direction.z >= 0) ? comp.worldAABB.maxPoint.z : comp.worldAABB.minPoint.z;
|
||||
|
||||
double thickness = std::abs((maxSupport - minSupport).dot(direction));
|
||||
|
||||
projections.push_back({support, thickness, comp.featureId});
|
||||
}
|
||||
|
||||
// Add all frontmost components in this direction to outer surface set
|
||||
for (int id : candidateIds) {
|
||||
outerComponentIds.insert(id);
|
||||
// Sort by support value (highest first)
|
||||
std::sort(projections.begin(), projections.end(),
|
||||
[](const ProjectionData& a, const ProjectionData& b) {
|
||||
return a.support > b.support;
|
||||
});
|
||||
|
||||
if (projections.empty()) continue;
|
||||
|
||||
double bestSupport = projections.front().support;
|
||||
|
||||
// Calculate median thickness for adaptive window
|
||||
std::vector<double> thicknesses;
|
||||
thicknesses.reserve(projections.size());
|
||||
for (const auto& p : projections) {
|
||||
thicknesses.push_back(p.thickness);
|
||||
}
|
||||
std::nth_element(thicknesses.begin(),
|
||||
thicknesses.begin() + thicknesses.size() / 2,
|
||||
thicknesses.end());
|
||||
double medianThickness = thicknesses[thicknesses.size() / 2];
|
||||
|
||||
// Adaptive depth window (max of absolute and relative)
|
||||
double assemblyDiagonal = globalAABB.getDiagonalLength();
|
||||
double absoluteWindow = std::max(1e-6, 0.002 * assemblyDiagonal); // 0.2% of diagonal
|
||||
double relativeWindow = 0.15 * medianThickness; // 15% of median thickness
|
||||
double depthWindow = std::max(absoluteWindow, relativeWindow);
|
||||
|
||||
// Top-K fallback to ensure minimum visible components
|
||||
int topK = std::min<int>(12, std::max<int>(3, (int)std::sqrt(components.size())));
|
||||
|
||||
// Mark visible components (within window OR in top-K)
|
||||
int rank = 0;
|
||||
for (const auto& proj : projections) {
|
||||
if ((proj.support >= bestSupport - depthWindow) || (rank < topK)) {
|
||||
visibilityVotes[proj.featureId]++;
|
||||
rank++;
|
||||
} else {
|
||||
break; // Components further back are not visible
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 5: Determine outer components based on voting threshold
|
||||
double minVisibilityRatio = 0.08; // At least 8% of directions
|
||||
int minVotes = std::max(3, (int)(minVisibilityRatio * numDirections));
|
||||
|
||||
for (const auto& kvp : visibilityVotes) {
|
||||
if (kvp.second >= minVotes) {
|
||||
outerComponentIds.insert(kvp.first);
|
||||
}
|
||||
}
|
||||
|
||||
// Step 6: Apply safety check - ensure at least some components are marked as outer
|
||||
if (outerComponentIds.empty() && !components.empty()) {
|
||||
// Fallback: mark components on assembly boundary as outer
|
||||
double assemblyDiagonal = globalAABB.getDiagonalLength();
|
||||
for (const ComponentItem& comp : components) {
|
||||
// Check if component AABB touches assembly boundary
|
||||
double boundaryTolerance = assemblyDiagonal * 0.005; // 0.5% tolerance for tighter boundary detection
|
||||
|
||||
@ -277,18 +277,18 @@ public:
|
||||
};
|
||||
|
||||
struct ShellAnalysisParameters {
|
||||
bool preserve_external_surfaces;
|
||||
double min_wall_thickness;
|
||||
double confidence_threshold;
|
||||
int total_features;
|
||||
int deletable_features;
|
||||
int preserved_features;
|
||||
bool assembly_analysis;
|
||||
std::string analysis_strategy = "bbox_surface_ownership_feature_analysis_optimized";
|
||||
int surface_count;
|
||||
int shell_surfaces;
|
||||
int internal_surfaces;
|
||||
int shell_feature_whitelist;
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,18 +0,0 @@
|
||||
C:\Users\sladr\source\repos\MFCCreoDll\AuthManager.cpp;C:\Users\sladr\source\repos\MFCCreoDll\MFCCreoDll\x64\Debug\AuthManager.obj
|
||||
C:\Users\sladr\source\repos\MFCCreoDll\CreoManager.cpp;C:\Users\sladr\source\repos\MFCCreoDll\MFCCreoDll\x64\Debug\CreoManager.obj
|
||||
C:\Users\sladr\source\repos\MFCCreoDll\GeometryAnalyzer.cpp;C:\Users\sladr\source\repos\MFCCreoDll\MFCCreoDll\x64\Debug\GeometryAnalyzer.obj
|
||||
C:\Users\sladr\source\repos\MFCCreoDll\HierarchyStatisticsAnalyzer.cpp;C:\Users\sladr\source\repos\MFCCreoDll\MFCCreoDll\x64\Debug\HierarchyStatisticsAnalyzer.obj
|
||||
C:\Users\sladr\source\repos\MFCCreoDll\HttpRouter.cpp;C:\Users\sladr\source\repos\MFCCreoDll\MFCCreoDll\x64\Debug\HttpRouter.obj
|
||||
C:\Users\sladr\source\repos\MFCCreoDll\HttpServer.cpp;C:\Users\sladr\source\repos\MFCCreoDll\MFCCreoDll\x64\Debug\HttpServer.obj
|
||||
C:\Users\sladr\source\repos\MFCCreoDll\JsonHelper.cpp;C:\Users\sladr\source\repos\MFCCreoDll\MFCCreoDll\x64\Debug\JsonHelper.obj
|
||||
C:\Users\sladr\source\repos\MFCCreoDll\Logger.cpp;C:\Users\sladr\source\repos\MFCCreoDll\MFCCreoDll\x64\Debug\Logger.obj
|
||||
C:\Users\sladr\source\repos\MFCCreoDll\MFCCreoDll.cpp;C:\Users\sladr\source\repos\MFCCreoDll\MFCCreoDll\x64\Debug\MFCCreoDll.obj
|
||||
C:\Users\sladr\source\repos\MFCCreoDll\ModelAnalyzer.cpp;C:\Users\sladr\source\repos\MFCCreoDll\MFCCreoDll\x64\Debug\ModelAnalyzer.obj
|
||||
C:\Users\sladr\source\repos\MFCCreoDll\ModelSearchEngine.cpp;C:\Users\sladr\source\repos\MFCCreoDll\MFCCreoDll\x64\Debug\ModelSearchEngine.obj
|
||||
C:\Users\sladr\source\repos\MFCCreoDll\ModelSearchHandler.cpp;C:\Users\sladr\source\repos\MFCCreoDll\MFCCreoDll\x64\Debug\ModelSearchHandler.obj
|
||||
C:\Users\sladr\source\repos\MFCCreoDll\PathDeleteManager.cpp;C:\Users\sladr\source\repos\MFCCreoDll\MFCCreoDll\x64\Debug\PathDeleteManager.obj
|
||||
C:\Users\sladr\source\repos\MFCCreoDll\pch.cpp;C:\Users\sladr\source\repos\MFCCreoDll\MFCCreoDll\x64\Debug\pch.obj
|
||||
C:\Users\sladr\source\repos\MFCCreoDll\ServerManager.cpp;C:\Users\sladr\source\repos\MFCCreoDll\MFCCreoDll\x64\Debug\ServerManager.obj
|
||||
C:\Users\sladr\source\repos\MFCCreoDll\ShellExportHandler.cpp;C:\Users\sladr\source\repos\MFCCreoDll\MFCCreoDll\x64\Debug\ShellExportHandler.obj
|
||||
C:\Users\sladr\source\repos\MFCCreoDll\ShrinkwrapManager.cpp;C:\Users\sladr\source\repos\MFCCreoDll\MFCCreoDll\x64\Debug\ShrinkwrapManager.obj
|
||||
C:\Users\sladr\source\repos\MFCCreoDll\WebSocketServer.cpp;C:\Users\sladr\source\repos\MFCCreoDll\MFCCreoDll\x64\Debug\WebSocketServer.obj
|
||||
Binary file not shown.
Binary file not shown.
@ -1,3 +0,0 @@
|
||||
^C:\USERS\SLADR\SOURCE\REPOS\MFCCREODLL\MFCCREODLL\X64\DEBUG\AUTHMANAGER.OBJ|C:\USERS\SLADR\SOURCE\REPOS\MFCCREODLL\MFCCREODLL\X64\DEBUG\CREOMANAGER.OBJ|C:\USERS\SLADR\SOURCE\REPOS\MFCCREODLL\MFCCREODLL\X64\DEBUG\GEOMETRYANALYZER.OBJ|C:\USERS\SLADR\SOURCE\REPOS\MFCCREODLL\MFCCREODLL\X64\DEBUG\HIERARCHYSTATISTICSANALYZER.OBJ|C:\USERS\SLADR\SOURCE\REPOS\MFCCREODLL\MFCCREODLL\X64\DEBUG\HTTPROUTER.OBJ|C:\USERS\SLADR\SOURCE\REPOS\MFCCREODLL\MFCCREODLL\X64\DEBUG\HTTPSERVER.OBJ|C:\USERS\SLADR\SOURCE\REPOS\MFCCREODLL\MFCCREODLL\X64\DEBUG\JSONHELPER.OBJ|C:\USERS\SLADR\SOURCE\REPOS\MFCCREODLL\MFCCREODLL\X64\DEBUG\LOGGER.OBJ|C:\USERS\SLADR\SOURCE\REPOS\MFCCREODLL\MFCCREODLL\X64\DEBUG\MFCCREODLL.OBJ|C:\USERS\SLADR\SOURCE\REPOS\MFCCREODLL\MFCCREODLL\X64\DEBUG\MFCCREODLL.RES|C:\USERS\SLADR\SOURCE\REPOS\MFCCREODLL\MFCCREODLL\X64\DEBUG\MODELANALYZER.OBJ|C:\USERS\SLADR\SOURCE\REPOS\MFCCREODLL\MFCCREODLL\X64\DEBUG\MODELSEARCHENGINE.OBJ|C:\USERS\SLADR\SOURCE\REPOS\MFCCREODLL\MFCCREODLL\X64\DEBUG\MODELSEARCHHANDLER.OBJ|C:\USERS\SLADR\SOURCE\REPOS\MFCCREODLL\MFCCREODLL\X64\DEBUG\PATHDELETEMANAGER.OBJ|C:\USERS\SLADR\SOURCE\REPOS\MFCCREODLL\MFCCREODLL\X64\DEBUG\PCH.OBJ|C:\USERS\SLADR\SOURCE\REPOS\MFCCREODLL\MFCCREODLL\X64\DEBUG\SERVERMANAGER.OBJ|C:\USERS\SLADR\SOURCE\REPOS\MFCCREODLL\MFCCREODLL\X64\DEBUG\SHELLEXPORTHANDLER.OBJ|C:\USERS\SLADR\SOURCE\REPOS\MFCCREODLL\MFCCREODLL\X64\DEBUG\SHRINKWRAPMANAGER.OBJ|C:\USERS\SLADR\SOURCE\REPOS\MFCCREODLL\MFCCREODLL\X64\DEBUG\WEBSOCKETSERVER.OBJ
|
||||
C:\Users\sladr\source\repos\MFCCreoDll\x64\Debug\MFCCreoDll.lib
|
||||
C:\Users\sladr\source\repos\MFCCreoDll\x64\Debug\MFCCreoDll.EXP
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user