Merge pull request '修复 XEquipment 外壳/Impl 分离机制的 M1-M7 缺陷' (#82) from company-laptop/fix-xequipment-m1-m7 into main

Reviewed-on: #82
Reviewed-by: gjm <littleoldpan@163.com>
This commit was merged in pull request #82.
This commit is contained in:
gjm committed 2026-10-27 09:58:07 +08:00
commit a51a550a99
4 files changed
+67 -28

No files matched your search

@@ -34,6 +34,9 @@ public:
, CString &subTyp);
protected:
// 所有权契约:impl 只保存外壳 m_mapSpecXData 的地址,不拥有参数数据。
// makeSelf() 必须传入“新外壳”的 map 指针;把同一个 impl 指针直接挂到另一个外壳上,
// 会让它继续读写旧外壳的参数。
AecDbObjXDataMap *m_pXDataMap;
};
@@ -245,14 +245,17 @@ Acad::ErrorStatus AecDbXEquipment::copyFrom(const AcRxObject* pSrc)
AssertWriteEnabled();
AecDbXEquipment *pSrcEqu = AecDbXEquipment::cast(pSrc);
if (!pSrcEqu) return Acad::eInvalidInput;
// 基类链通过 CopyObject(dwgOut -> dwgIn) 深拷参数,dwgInFields 内会重建 m_pImpl
Acad::ErrorStatus es = AecDbBDPipeBase::copyFrom(pSrc);
if (es != Acad::eOk) return es;
if (!m_pImpl)
m_pImpl = createParamEquImpl(GetType(), false);
// 放在重建之后:工厂里的 getInterfaces 可能覆盖读进来的管嘴
m_interfaces = pSrcEqu->m_interfaces;
return Acad::eOk;
//AssertWriteEnabled();
//AecDbXEquipment *pSrcEqu = AecDbXEquipment::cast(pSrc);
//if (!pSrcEqu) return Acad::eInvalidInput;
//m_mapSpecXData.CopyFrom(pSrcEqu->GetSpecialtyData());
//m_pImpl = pSrcEqu->cloneImpl(&m_mapSpecXData);
//return Acad::eOk;
}
Acad::ErrorStatus AecDbXEquipment::copyFrom2(const AcRxObject* pSrc)
@@ -260,8 +263,15 @@ Acad::ErrorStatus AecDbXEquipment::copyFrom2(const AcRxObject* pSrc)
AssertWriteEnabled();
AecDbXEquipment *pSrcEqu = AecDbXEquipment::cast(pSrc);
if (!pSrcEqu) return Acad::eInvalidInput;
m_mapSpecXData.CopyFrom(pSrcEqu->GetSpecialtyData());
m_pImpl = pSrcEqu->cloneImpl(&m_mapSpecXData);
// 先克隆成功再替换:cloneImpl 在源对象没有 impl 时返回 NULL
XEquipmentImplBase *pNewImpl = pSrcEqu->cloneImpl(&m_mapSpecXData);
DELETE_PTR(m_pImpl);
m_pImpl = pNewImpl;
if (!m_pImpl)
m_pImpl = createParamEquImpl(GetType(), false);
return Acad::eOk;
}
@@ -647,6 +657,8 @@ XEquipmentImplBase* AecDbXEquipment::createParamEquImpl(const int & type, bool b
return NULL;
}
// 工厂成功后替换旧 impl(inplace 编辑会对同一实体重复调用)
DELETE_PTR(m_pImpl);
m_pImpl = pImp;
// 接口生成一下
@@ -738,11 +750,19 @@ int AecDbXEquipment::GetSectionDraw(const AcGePoint3d& ptFr, const AcGePoint3d&
void AecDbXEquipment::draw3dByImp()
{
if (!m_pImpl) return;
RemoveAllX3dPart();
// 先画到临时数组,成功后再整体替换缓存:各设备 draw3d 在取数失败时会中途 return,
// 直接往缓存里 add 会让设备停留在“部分更新”状态。
AcDbVoidPtrArray ar;
m_pImpl->draw3d(ar);
m_pImpl->getInterfaces(m_interfaces);
if (ar.isEmpty() && !Get3DBuffer().isEmpty())
{
acutPrintf(_T("\n设备参数绘制失败,保留原有三维显示。"));
return;
}
RemoveAllX3dPart();
for (int i = 0; i < ar.length(); ++i)
{
@@ -751,6 +771,8 @@ void AecDbXEquipment::draw3dByImp()
AddX3dPart(pPart, (AcDb::BoolOperType)pPart->GetBoolOperFor());
}
m_pImpl->getInterfaces(m_interfaces);
}
bool AecDbXEquipment::isType(AcDbObjectId &id, const int &type)
@@ -767,6 +789,25 @@ bool AecDbXEquipment::isType(AecDbXEquipment *pEqu, const int &type)
return pEqu->GetType() == type;
}
AecDbXEquipment* AecDbXEquipment::makeTempClone() const
{
AecDbXEquipment *pNew = (AecDbXEquipment *)clone();
if (!pNew) return NULL;
// clone() 只带走了 m_interfaces,参数和 impl 必须靠 copyFrom2 补齐
pNew->copyFrom2(this);
pNew->Clean3DBuffer();
int count(GetX3dPartCount());
for (int i(0); i < count; ++i)
{
AecDbX3dPart *pPart = new AecDbX3dPart;
pPart->CopyFrom(GetX3dPart(i));
pNew->AddX3dPart(pPart);
}
return pNew;
}
SHJson::WValue& AecDbXEquipment::ToJson(bool bExprotGeo) const
{
using namespace SHJson;
@@ -776,20 +817,12 @@ SHJson::WValue& AecDbXEquipment::ToJson(bool bExprotGeo) const
AcGeVector3d vtDir;
GetInsert(ptIns, vtDir);
AecDbXEquipment *p = (AecDbXEquipment *)clone();
AecDbXEquipment *p = makeTempClone();
if (!p)
return AecDbBDPipeBase::ToJson(bExprotGeo);
std::shared_ptr<AecDbXEquipment> pNew(p);
pNew->copyFrom2(this);
pNew->Clean3DBuffer();
int count(GetX3dPartCount());
for (int i(0); i < count; ++i)
{
AecDbX3dPart *pPart = new AecDbX3dPart;
pPart->CopyFrom(GetX3dPart(i));
p->AddX3dPart(pPart);
}
// 现在需要将pNew移动到原点,并把方向置为x方向
AcGeMatrix3d mat;
mat.setToTranslation(-ptIns.asVector());
@@ -484,8 +484,8 @@ namespace
}
else if (sWildCard.CompareNoCase(_T("%s")) == 0) // 字符串
{
ss = va_arg(vlist, TCHAR *);
mem_size += ss.GetLength() * sizeof(TCHAR *);
ss = va_arg(vlist, LPCTSTR);
mem_size += ss.GetLength() * sizeof(TCHAR);
}
}
va_end(vlist);
@@ -518,7 +518,7 @@ namespace
}
else if (sWildCard.CompareNoCase(_T("%s")) == 0) // 字符串
{
ss = va_arg(vlist, TCHAR *);
ss = va_arg(vlist, LPCTSTR);
::memcpy(pBuf + iSeek, ss.GetBuffer(), ss.GetLength() * sizeof(TCHAR));
iSeek += ss.GetLength() * sizeof(TCHAR);
ss.ReleaseBuffer();
@@ -2285,7 +2285,7 @@ namespace XGESHAN
GETXDATA(type);
return GET_UNIQUE_NAME(XGC, %f%f%f%f%f%f%f%f%f%f%f%f%s
, D1, D2, B, B1, B2, A, B3, H, H1, L1, L2, T, type);
, D1, D2, B, B1, B2, A, B3, H, H1, L1, L2, T, (LPCTSTR)type);
}
bool XGC::GetSpec(SH_BIM_BLOCK &spec)
@@ -3151,7 +3151,7 @@ namespace XGESHAN
CString bRect;
GETXDATA(bRect);
return GET_UNIQUE_NAME(BS, %f%f%f%f%f%s, S, B, H, H1, W1, bRect);
return GET_UNIQUE_NAME(BS, %f%f%f%f%f%s, S, B, H, H1, W1, (LPCTSTR)bRect);
}
bool BS::GetSpec(SH_BIM_BLOCK &spec)
@@ -3689,7 +3689,7 @@ namespace XGESHAN
GETXDATA(style);
GETXDATA(num);
return GET_UNIQUE_NAME(XL, %f%f%f%f%f%f%f%s%d, W, H, B, A, B1, L1, T, style, num);
return GET_UNIQUE_NAME(XL, %f%f%f%f%f%f%f%s%f, W, H, B, A, B1, L1, T, (LPCTSTR)style, num);
}
bool XL::GetSpec(SH_BIM_BLOCK &spec)
@@ -8746,7 +8746,7 @@ namespace XGUANXIANG
GETXDATA(num);
return GET_UNIQUE_NAME(GUANXIANG_I, %f%f%f%f%f%f%f%f%f%f%f%f%f%s%s%s%s%s
, D, H, H1, H2, D1, D2, L11, W11, H11, H3, R, L1, R2
, SG, XG, style, type, num);
, (LPCTSTR)SG, (LPCTSTR)XG, (LPCTSTR)style, (LPCTSTR)type, (LPCTSTR)num);
}
#pragma endregion
}
@@ -9727,7 +9727,7 @@ namespace XLABAKOU
GETXDATA(HD);
GETXDATA(BZ);
return GET_UNIQUE_NAME(YUANXINGLABAKOU, %f%f%f%f%s, RKDN, CKDN, CD, HD, BZ);
return GET_UNIQUE_NAME(YUANXINGLABAKOU, %f%f%f%f%s, RKDN, CKDN, CD, HD, (LPCTSTR)BZ);
}
#pragma endregion
}
@@ -271,6 +271,9 @@ public:
virtual bool SetProperties(SimpleProperty::PropertySetByName &porpertys);
private:
// ToJson 专用:clone() 只得到空壳,需要再 copyFrom2 补参数/impl 并单独拷 3D part
AecDbXEquipment* makeTempClone() const;
XEquipmentImplBase *m_pImpl;
protected: