fix: correct ray-AABB intersection algorithm to handle rays starting inside AABB

- Fixed intersection distance calculation to handle three cases:
  - Ray starts outside AABB: use entry point (tMin)
  - Ray starts inside AABB: use exit point (tMax)
  - AABB behind ray: skip intersection
- This fixes the issue where no intersections were detected (intersections=0)
This commit is contained in:
sladro 2025-09-20 10:32:59 +08:00
parent a6d32180cb
commit 6fd84e4ca3
24 changed files with 63 additions and 20 deletions

View File

@ -1562,20 +1562,7 @@ CreoManager::HierarchyDeleteResult CreoManager::DeleteHierarchyComponents(const
CreoManager::ShellAnalysisResult CreoManager::AnalyzeShellFeaturesEnhanced(const ShellAnalysisRequest& request) {
ShellAnalysisResult result;
// Create analysis log file immediately
try {
SessionInfo sessionInfo = GetSessionInfo();
if (sessionInfo.is_valid) {
xstring workdir = sessionInfo.session->GetCurrentDirectory();
std::string workingDir = XStringToString(workdir);
std::string logPath = workingDir + "\\shell_analysis_start.txt";
std::ofstream logFile(logPath);
logFile << "Shell Analysis Started" << std::endl;
logFile << "Time: " << GetCurrentTimeString() << std::endl;
logFile << "Working Directory: " << workingDir << std::endl;
logFile.close();
}
} catch (...) {}
// Removed shell_analysis_start.txt creation
try {
// Get session
@ -3559,12 +3546,12 @@ bool CreoManager::IsComponentBlockedFromCenter(const Vector3D& globalCenter,
// We only care about intersections beyond this distance (outward extension)
double distToComponentCenter = (componentCenter - globalCenter).length();
// Debug for 12V4000G03
bool isTarget12v = (component.name.find("12v4000g03") != std::string::npos ||
component.name.find("12V4000G03") != std::string::npos);
// Debug for ID 7 (12V4000G03)
bool isTarget12v = (component.featureId == 7);
int checkedCount = 0;
int intersectionCount = 0;
int beyondCount = 0; // Count intersections beyond component center
std::string nearestBlocker;
double nearestDistance = 1e9;
@ -3617,10 +3604,22 @@ bool CreoManager::IsComponentBlockedFromCenter(const Vector3D& globalCenter,
}
}
// Check if intersection exists and is beyond the component center (outward extension)
if (tMin <= tMax && tMin >= 0) {
// Check if intersection exists
if (tMin <= tMax) {
// Calculate the actual distance of the intersection point
double intersectionDistance = tMin;
double intersectionDistance;
if (tMin >= 0) {
// Ray starts outside AABB, use entry point
intersectionDistance = tMin;
} else if (tMax >= 0) {
// Ray starts inside AABB, use exit point
intersectionDistance = tMax;
} else {
// AABB is completely behind ray, no forward intersection
continue;
}
intersectionCount++;
// Track nearest potential blocker for debugging
@ -3632,11 +3631,55 @@ bool CreoManager::IsComponentBlockedFromCenter(const Vector3D& globalCenter,
// Only consider it blocked if intersection is beyond the component center
if (intersectionDistance > distToComponentCenter) {
beyondCount++;
if (isTarget12v && beyondCount == 1) { // Log first blocker found
try {
SessionInfo sessionInfo = GetSessionInfo();
if (sessionInfo.is_valid) {
xstring workdir = sessionInfo.session->GetCurrentDirectory();
std::string workingDir = XStringToString(workdir);
std::string logPath = workingDir + "\\12v4000g03_visibility.txt";
std::ofstream logFile(logPath, std::ios::app);
if (logFile.is_open()) {
logFile << " BLOCKED BY: " << otherComp.name
<< " at distance " << intersectionDistance
<< " (center at " << distToComponentCenter << ")" << std::endl;
logFile.close();
}
}
} catch (...) {}
}
return true; // Component is blocked by something in the outward direction
}
}
}
// Log ray test summary for ID 7
if (isTarget12v) {
static int rayDirCount = 0;
rayDirCount++;
if (rayDirCount <= 6) {
try {
SessionInfo sessionInfo = GetSessionInfo();
if (sessionInfo.is_valid) {
xstring workdir = sessionInfo.session->GetCurrentDirectory();
std::string workingDir = XStringToString(workdir);
std::string logPath = workingDir + "\\12v4000g03_visibility.txt";
std::ofstream logFile(logPath, std::ios::app);
if (logFile.is_open()) {
logFile << " Ray stats: checked=" << checkedCount
<< ", intersections=" << intersectionCount
<< ", beyond_center=" << beyondCount;
if (!nearestBlocker.empty()) {
logFile << " (nearest: " << nearestBlocker << ")";
}
logFile << std::endl;
logFile.close();
}
}
} catch (...) {}
}
}
return false; // Component is not blocked (is outer shell)
}

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.