fix: HLR 退化圆弧按来源实体直径判断,并支持爬梯
在删除圆心角为 PI 的退化圆弧时,增加直径比较: - 弯头(eElbow / eReduceElbow):带法兰(连接类型 3/5)取法兰外径 m_dInterfaceD, 否则取画法直径 m_dD; - 爬梯(AecDbClimbStair):取踏管直径 ClimbStair::dd。 仅当圆弧直径大于来源实体直径时才删除。 getElbowDiameter 改为 getSourceDiameter,removeFittingDegenerateArcs 改为 removeDegenerateArcs(已不止管件)。
This commit is contained in:
1 parent
c0c04952dc
commit
bbb899c0a0
1 file changed
+61
-17
@@ -7,6 +7,7 @@
|
||||
#include "HlrCutOption.h"
|
||||
#include "aecdbewpipebase.h"
|
||||
#include "AecDbEwFitting.h"
|
||||
#include "AecDbClimbStair.h"
|
||||
#include "compare_double.h"
|
||||
#include "simpleproperty.h"
|
||||
#include "hlrcommands.h"
|
||||
@@ -535,9 +536,14 @@ namespace
|
||||
//#endif
|
||||
}
|
||||
|
||||
// 判断指定 id 的实体是否为 AecDbEwFitting。
|
||||
bool isFittingId(const AcDbObjectId &id)
|
||||
// 取得指定 id 对应实体用于与 HLR 结果圆弧比较的"直径"。目前处理两类来源:
|
||||
// 弯头(eElbow / eReduceElbow):带法兰(连接类型 3 法兰管 / 5 法兰管线)时取法兰外径,
|
||||
// 否则取弯头画法直径;
|
||||
// 爬梯(AecDbClimbStair):取踏管直径。
|
||||
// 其他实体返回 false(不处理)。
|
||||
bool getSourceDiameter(const AcDbObjectId &id, double &dDiameter)
|
||||
{
|
||||
dDiameter = 0.0;
|
||||
if (id == AcDbObjectId::kNull)
|
||||
return false;
|
||||
|
||||
@@ -545,8 +551,37 @@ namespace
|
||||
if (ent.openStatus() != Acad::eOk)
|
||||
return false;
|
||||
|
||||
AcDbEntity *pEnt = ent;
|
||||
return AecDbEwFitting::cast(pEnt) != NULL;
|
||||
AcDbEntity *pEnt(ent);
|
||||
|
||||
// 爬梯:踏管直径
|
||||
AecDbClimbStair *pStair(AecDbClimbStair::cast(pEnt));
|
||||
if (pStair != NULL)
|
||||
{
|
||||
ClimbStair data;
|
||||
memset(&data, 0, sizeof(ClimbStair));
|
||||
pStair->GetClimbStairData(data);
|
||||
dDiameter = data.dd;
|
||||
return true;
|
||||
}
|
||||
|
||||
// 弯头
|
||||
AecDbEwFitting *pFit(AecDbEwFitting::cast(pEnt));
|
||||
if (pFit == NULL)
|
||||
return false;
|
||||
|
||||
const EFittingType eType(pFit->GetFittingType());
|
||||
if (eType != eElbow && eType != eReduceElbow)
|
||||
return false;
|
||||
|
||||
WPipe::PipeParam *pParam(pFit->GetPipeParam());
|
||||
if (pParam == NULL)
|
||||
return false;
|
||||
|
||||
const bool bFlange(pParam->m_nConnectType == 3 || pParam->m_nConnectType == 5);
|
||||
dDiameter = bFlange ? pParam->m_dInterfaceD : pParam->m_dD;
|
||||
|
||||
delete pParam;
|
||||
return true;
|
||||
}
|
||||
|
||||
// result2 的键是"产生该批结果的实体指针",这类实体没有 id(是补充实体)。
|
||||
@@ -569,32 +604,40 @@ namespace
|
||||
}
|
||||
|
||||
// 判断 HLR 结果实体是否为需要删除的"退化圆弧":
|
||||
// 实体是 AcDbArc,且圆心角为 PI(HLR 计算圆心角溢出后的特征)。
|
||||
bool isDegenerateArcEntity(AcDbEntity *pEnt)
|
||||
// 实体是 AcDbArc、圆心角为 PI(HLR 计算圆心角溢出后的特征),
|
||||
// 且其直径大于来源实体的直径(超出实体本身范围,属错误结果)。
|
||||
bool isDegenerateSourceArc(AcDbEntity *pEnt, const double &dSourceDiameter)
|
||||
{
|
||||
AcDbArc *pArc(AcDbArc::cast(pEnt));
|
||||
if (pArc == NULL)
|
||||
return false;
|
||||
|
||||
return COMPARE_DOUBLE::equal(pArc->totalAngle(), PI, 1e-9);
|
||||
if (!COMPARE_DOUBLE::equal(pArc->totalAngle(), PI, 1e-9))
|
||||
return false;
|
||||
|
||||
if (dSourceDiameter <= 1.e-6) // 取不到来源直径,无法比较,不删除
|
||||
return false;
|
||||
|
||||
return COMPARE_DOUBLE::up_zero(pArc->radius() * 2.0 - dSourceDiameter, 1e-6);
|
||||
}
|
||||
|
||||
// 删除 result1 / result2 中由 AecDbEwFitting 经 HLR 计算产生的、圆心角为 PI 的圆弧。
|
||||
// result1 的键是数据库实体 id,直接判断该 id 是否为 AecDbEwFitting;
|
||||
// result2 的键是无 id 的补充实体指针,需经 mpAdditional 反查归属的数据库实体 id 再判断。
|
||||
void removeFittingDegenerateArcs(IDMapEntities &result1
|
||||
// 删除 result1 / result2 中由弯头或爬梯经 HLR 计算产生的退化圆弧。
|
||||
// result1 的键是数据库实体 id,直接取该 id 对应实体的直径;
|
||||
// result2 的键是无 id 的补充实体指针,需经 mpAdditional 反查归属的数据库实体 id 再取直径。
|
||||
void removeDegenerateArcs(IDMapEntities &result1
|
||||
, EntMapEntities &result2
|
||||
, const IDMapEntities &mpAdditional)
|
||||
{
|
||||
IDMapEntities::iterator it(result1.begin());
|
||||
for (; it != result1.end(); ++it)
|
||||
{
|
||||
if (!isFittingId(it->first))
|
||||
double dDiameter(0.0);
|
||||
if (!getSourceDiameter(it->first, dDiameter))
|
||||
continue;
|
||||
|
||||
for (int i(it->second.length() - 1); i >= 0; --i)
|
||||
{
|
||||
if (isDegenerateArcEntity(it->second[i]))
|
||||
if (isDegenerateSourceArc(it->second[i], dDiameter))
|
||||
{
|
||||
delete it->second[i];
|
||||
it->second.removeAt(i);
|
||||
@@ -605,12 +648,13 @@ namespace
|
||||
EntMapEntities::iterator it2(result2.begin());
|
||||
for (; it2 != result2.end(); ++it2)
|
||||
{
|
||||
if (!isFittingId(fittingIdOfResultKey(it2->first, mpAdditional)))
|
||||
double dDiameter(0.0);
|
||||
if (!getSourceDiameter(fittingIdOfResultKey(it2->first, mpAdditional), dDiameter))
|
||||
continue;
|
||||
|
||||
for (int i(it2->second.length() - 1); i >= 0; --i)
|
||||
{
|
||||
if (isDegenerateArcEntity(it2->second[i]))
|
||||
if (isDegenerateSourceArc(it2->second[i], dDiameter))
|
||||
{
|
||||
delete it2->second[i];
|
||||
it2->second.removeAt(i);
|
||||
@@ -2051,8 +2095,8 @@ void AecDbXCamera::hlrCalc(AcDbObjectIdArray &arIds
|
||||
|
||||
HlrCalc(arIds, arAdditional_all, pVp.get(), control, result1, result2);
|
||||
|
||||
// 删除由 AecDbEwFitting 经 HLR 计算产生的"退化"圆弧(圆心角溢出为 PI)。
|
||||
removeFittingDegenerateArcs(result1, result2, mpAdditional);
|
||||
// 删除由弯头或爬梯经 HLR 计算产生的退化圆弧(圆心角溢出为 PI)。
|
||||
removeDegenerateArcs(result1, result2, mpAdditional);
|
||||
|
||||
if (result1.empty() && result2.empty())
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user