fix(HLR): 清理剖切结果中的退化圆弧,避免圆心角溢出生成反向大圆弧 #9

Merged
gjm merged 1 commits from company-desktop-computer/company-ai-dev AGit into main 2026-10-16 13:12:45 +08:00
Showing only changes of commit a1c7d39dc6 - Show all commits
@@ -534,6 +534,26 @@ namespace
//#endif
}
// 弧长/半径 的比值小于此值即视为"退化圆弧"(圆心角极小)。
const double kMinArcLengthRadiusRatio = 1e-6;
// 判断 HLR 结果实体是否为"退化圆弧":实体是 AcDbArc,且 弧长/半径 的比值极小。
// 这类圆弧的圆心角极小,HLR 计算时圆心角会溢出,使结果由"很小一段"变成
// "反向的大圆弧",需要从结果中删除。
bool isDegenerateArc(AcDbEntity *pEnt)
{
AcDbArc *pArc(AcDbArc::cast(pEnt));
if (pArc == NULL)
return false;
double dRadius(pArc->radius());
if (COMPARE_DOUBLE::equal_zero(dRadius, 1e-9))
return true; // 半径≈0,本身即退化
double dRatio(pArc->length() / dRadius);
return dRatio < kMinArcLengthRadiusRatio;
}
bool zeroLength(AcDbCurve *pCrv, const double &tol)
{
double dPEnd(.0), dDist(.0);
@@ -1966,6 +1986,36 @@ void AecDbXCamera::hlrCalc(AcDbObjectIdArray &arIds
HlrCalc(arIds, arAdditional_all, pVp.get(), control, result1, result2);
// 删除 HLR 计算中"退化"的圆弧(弧长/半径 比值极小)。
// 这类圆弧圆心角极小,计算时会溢出,由"很小一段"变成"反向的大圆弧"。
{
IDMapEntities::iterator it(result1.begin());
for (; it != result1.end(); ++it)
{
for (int i(it->second.length() - 1); i >= 0; --i)
{
if (isDegenerateArc(it->second[i]))
{
delete it->second[i];
it->second.removeAt(i);
}
}
}
EntMapEntities::iterator it2(result2.begin());
for (; it2 != result2.end(); ++it2)
{
for (int i(it2->second.length() - 1); i >= 0; --i)
{
if (isDegenerateArc(it2->second[i]))
{
delete it2->second[i];
it2->second.removeAt(i);
}
}
}
}
if (result1.empty() && result2.empty())
{
// 如果实体的PreprocessForHlr函数内,设置了 HLR_CALC,从而影响实体的 Draw3d 函数的返回