fix: 修复 AecDbEwEquipment 的 10 处逻辑缺陷
3.2 subErase:sName.Find(_T("接头")) 当布尔用,找不到返回 -1 也为真,
整个条件恒成立,删除任何设备都走阀门/接头的合并管线分支。补 != -1。
3.3 DrawHandFlg:else 分支写成 sFlag == _T("Y"),液动阀(3)符号文字一直是空串。
3.4 ProcessHlrResult:遍历 map 时 erase(it) 之后仍然 ++it。改成 while +
erase(it++),没有用 it = erase(it),因为 R190 走 C++98 标准,
C++03 的 map::erase(iterator) 返回 void。
3.5 GetSectionDraw:返回 nCount - nCoundPre(调用前减调用后),恒为 0 或负数。
改为 nCoundPre - nCount。全库调用点都忽略返回值,此前无实际故障。
3.8 copyFrom:补拷 m_bVert / m_idDash / m_idCenter。原来复制粘贴竖放阀门
会变横放,虚线与中心线的图层也丢失。
3.9 MakeBlockRefSet:判断的是累加器 ext 而不是本次的 extAdd,第一轮 ext 还是
空状态,第一个实体的范围永远加不进去;块参照分支不 continue,extAdd 会
沿用上一轮的值被重复累加。改为块参照跳过、extAdd 每轮新建并检查返回值。
3.10 byJson:br._len 是字节数,却按 new PVOID[br._len] 分配、按
sizeof(PVOID)*br._len 拷贝,源缓冲区越界读 7 倍。改为按字节分配拷贝,
并用 br._len 覆盖 m_nSize。
3.11 dwgInFieldsForXPrim:加 16MB 上限(kMaxXPrimDataSize),超限置
eInvalidInput 让整个 dwgInFields 退出;readBytes 检查返回值,失败时释放。
3.13 GetBodyBox:恒返回 TRUE,调用方无法区分是否取到几何;_ext 在循环外定义,
会把上一轮的累积结果重复并入。改为返回实际结果、每轮新建 _ext。
3.14 clearGeoBuffer:函数体只有 AssertWriteEnabled(),改完参数几何不刷新。
改为 Clean2DBuffer() + Clean3DBuffer()。
未处理,见文档 5.4:3.6 HLR_CALC 序列化(要动 AecDbObjXDataMap 公共类)、
3.7 GetInterface 数组版单位(影响 67 处调用)、3.12 mat4 双次变换(需确认是否刻意)。
This commit is contained in:
1 parent
44f53dede4
commit
f668e29b6c
2 files changed
+142
-47
No files matched your search
@@ -76,6 +76,9 @@ struct Point2d
|
||||
|
||||
namespace
|
||||
{
|
||||
//单个几何单元的参数块上限:正常只有几十字节到几十 KB,超出即视为图纸损坏
|
||||
const Adesk::Int32 kMaxXPrimDataSize = 16 * 1024 * 1024;
|
||||
|
||||
bool isValidExtents(const AcDbExtents &ext)
|
||||
{
|
||||
// 检查是否仍然处于初始化的“反转”状态
|
||||
@@ -188,10 +191,24 @@ namespace
|
||||
pFiler->readInt32(&nSize);
|
||||
pSolid->m_nSize = nSize;
|
||||
|
||||
//单个单元的参数块只有几十字节到几十 KB,超出上限说明图纸损坏。
|
||||
//直接 new byte[巨量] 会当场失败,这里标记文件错误让整个 dwgInFields 退出
|
||||
if (pSolid->m_nSize > kMaxXPrimDataSize)
|
||||
{
|
||||
pSolid->m_nSize = 0;
|
||||
pFiler->setFilerStatus(Acad::eInvalidInput);
|
||||
return pSolid;
|
||||
}
|
||||
|
||||
if (pSolid->m_nSize > 0)
|
||||
{
|
||||
pSolid->m_pData = new byte[pSolid->m_nSize];
|
||||
pFiler->readBytes(pSolid->m_pData, (Adesk::UInt32)pSolid->m_nSize);
|
||||
if (pFiler->readBytes(pSolid->m_pData, (Adesk::UInt32)pSolid->m_nSize) != Acad::eOk)
|
||||
{
|
||||
delete[] (byte*)pSolid->m_pData;
|
||||
pSolid->m_pData = NULL;
|
||||
pSolid->m_nSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//ID 存2个32为
|
||||
@@ -825,8 +842,15 @@ namespace
|
||||
it = v.FindMember(_T("__pData__"));
|
||||
if (it == v.MemberEnd()) return false;
|
||||
GEO2JSON::binary br(it->value);
|
||||
p->m_pData = new PVOID[br._len];
|
||||
::memcpy(p->m_pData, br._data, sizeof(PVOID) * br._len);
|
||||
//br._len 是字节数,与 __nSize__ 同单位。原来按 PVOID 个数分配、
|
||||
//再按 sizeof(PVOID)*len 拷贝,源缓冲区会越界读 7 倍。
|
||||
//两者不一致说明 JSON 被改过,按实际数据长度为准
|
||||
p->m_nSize = (int)br._len;
|
||||
if (br._len > 0 && br._data != NULL)
|
||||
{
|
||||
p->m_pData = new byte[br._len];
|
||||
::memcpy(p->m_pData, br._data, br._len);
|
||||
}
|
||||
|
||||
it = v.FindMember(_T("__nActiveInf__"));
|
||||
if (it == v.MemberEnd()) return false;
|
||||
@@ -2110,7 +2134,11 @@ Acad::ErrorStatus AecDbEwEquipment::subErase(Adesk::Boolean erasing)
|
||||
int nVal = 1;
|
||||
m_mapSpecXData.GetAt(PIPE_VALVE, nVal);
|
||||
|
||||
if (eSubType == eValve || sName.Find(_T("阀") ) != -1 || sName.Find(_T("接头")))
|
||||
//第三个条件原来写成 sName.Find(_T("接头")),Find 找不到返回 -1,
|
||||
//非 0 即真,整个条件恒成立,删除任何设备都会走下面的合并管线逻辑
|
||||
if (eSubType == eValve
|
||||
|| sName.Find(_T("阀")) != -1
|
||||
|| sName.Find(_T("接头")) != -1)
|
||||
{
|
||||
AecEqui::ValveType eVlvType = (AecEqui::ValveType)nVal;
|
||||
//if (eVlvType >= AecEqui::eGateVlv && eVlvType <= AecEqui::eJYF)
|
||||
@@ -2184,6 +2212,13 @@ Acad::ErrorStatus AecDbEwEquipment::copyFrom(const AcRxObject* pSrc)
|
||||
m_nInfActive = pImp->m_nInfActive;
|
||||
m_ptInsert = pImp->m_ptInsert;
|
||||
m_vtDir = pImp->m_vtDir;
|
||||
|
||||
//这三个原来漏拷:m_bVert 决定阀门横放还是竖放(TransformEntity 要用),
|
||||
//m_idDash / m_idCenter 是虚线与中心线所在的图层,丢了会跑到默认图层
|
||||
m_bVert = pImp->m_bVert;
|
||||
m_idDash = pImp->m_idDash;
|
||||
m_idCenter = pImp->m_idCenter;
|
||||
|
||||
AecEqui::XPrimData* pSolid = NULL;
|
||||
AecEqui::XPrimData* pSolid2 = NULL;
|
||||
|
||||
@@ -2646,7 +2681,7 @@ Acad::ErrorStatus AecDbEwEquipment::DrawHandFlg(AcGiDraw &dc) const
|
||||
CString sFlag(_T(""));
|
||||
if (nVt == 1) sFlag = _T("M");
|
||||
else if (nVt == 2) sFlag = _T("G");
|
||||
else sFlag == _T("Y");
|
||||
else sFlag = _T("Y"); //液动;原来写成 ==,sFlag 一直是空串
|
||||
|
||||
AecInterface inf1, inf2;
|
||||
GetInterface(0, inf1);
|
||||
@@ -4220,14 +4255,21 @@ int AecDbEwEquipment::GetBodyBox(AcDbExtents& ext) const
|
||||
Draw3d(dc);
|
||||
}
|
||||
|
||||
AcDbExtents _ext;
|
||||
//原来恒返回 TRUE,调用方无法区分"没取到几何"。
|
||||
//_ext 也改为每轮新建,避免把上一轮的累积结果重复并入
|
||||
BOOL bRet(FALSE);
|
||||
for (size_t i = 0; i < ar3D.length(); i++)
|
||||
{
|
||||
AcDbEntity *p = (AcDbEntity*)ar3D[(int)i];
|
||||
p->getGeomExtents(_ext);
|
||||
if (p == NULL) continue;
|
||||
|
||||
AcDbExtents _ext;
|
||||
if (p->getGeomExtents(_ext) != Acad::eOk) continue;
|
||||
|
||||
ext.addExt(_ext);
|
||||
bRet = TRUE;
|
||||
}
|
||||
return TRUE;
|
||||
return bRet;
|
||||
}
|
||||
|
||||
AecDbObjXDataMap* AecDbEwEquipment::GetSpecialtyData(AcDb::OpenMode bMode)
|
||||
@@ -12540,15 +12582,26 @@ void AecDbEwEquipment::setSectionID(const ESection &es, AcDbObjectId & id)
|
||||
//取中心位置为做块的插入位置
|
||||
DLLIMPEXP bool MakeBlockRefSet(AcDbVoidPtrArray& arEntPtrs,const AcDbObjectId& idLay,Adesk::Boolean bDoSubent,LPCTSTR pszName,AcDbDatabase* pDb = NULL)
|
||||
{
|
||||
AcDbExtents ext, extAdd;
|
||||
AcDbExtents ext;
|
||||
AcDbEntity *pEnt = NULL;
|
||||
CString s;
|
||||
for (int i = 0;i < arEntPtrs.length();i++)
|
||||
{
|
||||
pEnt = (AcDbEntity*)arEntPtrs.at(i);
|
||||
if (!AcDbBlockReference::cast(pEnt))
|
||||
pEnt->getGeomExtents(extAdd);
|
||||
if (isValidExtents(ext))
|
||||
if (pEnt == NULL) continue;
|
||||
|
||||
//块参照本身没有几何。原来不跳过,extAdd 会保留上一轮的值被重复累加
|
||||
if (AcDbBlockReference::cast(pEnt))
|
||||
continue;
|
||||
|
||||
//每轮重新取,避免 getGeomExtents 失败时沿用上一轮的范围
|
||||
AcDbExtents extAdd;
|
||||
if (pEnt->getGeomExtents(extAdd) != Acad::eOk)
|
||||
continue;
|
||||
|
||||
//原来判断的是累加器 ext:第一轮它还是空状态,
|
||||
//第一个实体的范围永远加不进去
|
||||
if (isValidExtents(extAdd))
|
||||
ext.addExt(extAdd);
|
||||
}
|
||||
|
||||
@@ -12803,7 +12856,8 @@ int AecDbEwEquipment::GetSectionDraw(const AcGePoint3d& ptFr,const AcGePoint3d&
|
||||
GetSectionDraw(plan,vtTo,arRegionPtrs);
|
||||
|
||||
int nCoundPre = arRegionPtrs.length();
|
||||
return (nCount - nCoundPre);
|
||||
//返回本次新增的个数。原来写成 nCount - nCoundPre(调用前减调用后),恒为 0 或负数
|
||||
return (nCoundPre - nCount);
|
||||
}
|
||||
|
||||
bool AecDbEwEquipment::GetPositionGrip(int nIndex, AecGripData *&pGrip) const
|
||||
@@ -12915,6 +12969,11 @@ bool AecDbEwEquipment::ByJson(const SHJson::WValue &v)
|
||||
void AecDbEwEquipment::clearGeoBuffer()
|
||||
{
|
||||
AssertWriteEnabled();
|
||||
|
||||
//调用方(改参数、改颜色之后)期望清掉缓存强制重建,
|
||||
//原来函数体是空的,改完参数旧几何还在
|
||||
Clean2DBuffer();
|
||||
Clean3DBuffer();
|
||||
}
|
||||
|
||||
void AecDbEwEquipment::TransformEntity(AcDbEntity *p
|
||||
@@ -13179,13 +13238,14 @@ void AecDbEwEquipment::ProcessHlrResult(const AcArray<AcDbEntity *> &ar
|
||||
_ar.removeAll();
|
||||
|
||||
// 把 preAr 中的 region 生成的结果挑出来,不显示
|
||||
// 原来 erase(it) 之后仍然 ++it,迭代器已失效
|
||||
std::map<AcDbEntity *, AcArray<AcDbEntity *>>::iterator it(_preAr.begin());
|
||||
for (; it != _preAr.end(); ++it)
|
||||
while (it != _preAr.end())
|
||||
{
|
||||
if (AcDbRegion::cast(it->first))
|
||||
{
|
||||
_preAr.erase(it);
|
||||
}
|
||||
_preAr.erase(it++); //先取下一个迭代器再删当前
|
||||
else
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user