From 5a5cd087215ff9af87b3bb677fde1770e3fee217 Mon Sep 17 00:00:00 2001 From: company-desktop-computer Date: Thu, 22 Oct 2026 15:07:18 +0800 Subject: [PATCH 1/2] =?UTF-8?q?perf:=20X3dPart=20=E5=B8=83=E5=B0=94?= =?UTF-8?q?=E7=BB=93=E6=9E=9C=E6=94=B9=E4=B8=BA=E6=8C=89=E9=9C=80=E9=87=8D?= =?UTF-8?q?=E5=BB=BA=EF=BC=8C=E5=BC=80=E5=9B=BE=E4=B8=8D=E5=86=8D=E9=80=90?= =?UTF-8?q?=E4=BB=B6=E5=BB=BA=E4=BD=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 方案 A(见 AcDbX3dSolid-refactor-plan.md 第 13 节)。开图慢的瓶颈是 AecDbX3dPartEntity::dwgInFields 无条件调 m_pPart->Create(),每个 part 都要 N 次建体 + N 次布尔。 A1:引入 m_bDirty - AecDbX3dPart 增加 m_bDirty,构造/拷贝构造置 true - 15 个改参数的接口置脏:AddX3dSolid、RemoveAt、RemoveAll3dSolidRec、 SetOrgPoint、SetAxis、SetBoolOperFor、SetHide、SetActive、PeelOffTheSkin、 AddMove×2、ResetMove、AddRotate、ResetRotate、CopyFrom - 新增 Rebuild()(protected):清标志后无条件重建,原 Create() 的函数体 - 新增 EnsureCreated():m_bDirty 或 m_pSolid 为空时才 Rebuild Create() 保持「显式调用一律重建」的语义,内部转调 Rebuild()。原因是外部 有 10 处先取 GetX3dSolid(0) 直接改(如 AecDbBDPipeBase:941 调 TransformBy) 再调 Create(),部件感知不到这类改动,做成幂等会漏掉重建。 A2:开图不建几何 - AecDbX3dPartEntity::dwgInFields 去掉 m_pPart->Create(),由 AecDbX3dPart::dwgInFields 结尾置脏 - 读入口统一先 EnsureCreated:CreateDraw3dSolid、Draw3d、getOsnapPoints、 GetForHouseSubtract 收益:关闭/冻结图层、视口外、XREF/审核/发布等不绘制的场景完全省掉建体与 布尔;全图可见时开图时间下降、首次 regen 补回。 --- .../Code2026/CoreLibrary/AecDbX3dPart.cpp | 44 +++++++++++++++++++ .../CoreLibrary/AecDbX3dPartEntity.cpp | 2 +- SourceCode/Code2026/inc/AecDbX3dPart.h | 4 ++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/SourceCode/Code2026/CoreLibrary/AecDbX3dPart.cpp b/SourceCode/Code2026/CoreLibrary/AecDbX3dPart.cpp index 1d0dc88..ade4a5e 100644 --- a/SourceCode/Code2026/CoreLibrary/AecDbX3dPart.cpp +++ b/SourceCode/Code2026/CoreLibrary/AecDbX3dPart.cpp @@ -48,6 +48,7 @@ AecDbX3dPart::AecDbX3dPart(void) m_nBoolOper = 0; m_pSolidDraw = NULL; m_pSolid = NULL; + m_bDirty = true; m_sName = _T(""); m_sGUID = IDCreate(); m_bActive = false; @@ -60,6 +61,7 @@ AecDbX3dPart::AecDbX3dPart(const AecDbX3dPart& pPart) { m_pSolidDraw = NULL; m_pSolid = NULL; + m_bDirty = true; m_sName = pPart.m_sName; m_sGUID = pPart.m_sGUID; @@ -150,6 +152,7 @@ void AecDbX3dPart::ReCreateGUID() void AecDbX3dPart::AddX3dSolid(AcDbX3dSolid* pXSolid,AcDb::BoolOperType bType /*AcDb::kBoolUnite*/,bool bForHouseSub /*= false*/) { + m_bDirty = true; if (bType == AcDb::kBoolUnite) { m_arX3DSolidPtrsUnite.append(pXSolid); @@ -169,6 +172,7 @@ void AecDbX3dPart::AddX3dSolid(AcDbX3dSolid* pXSolid,AcDb::BoolOperType bType / void AecDbX3dPart::SetOrgPoint(const AcGePoint3d& ptOrg) { + m_bDirty = true; m_ptOrg = ptOrg; } @@ -467,6 +471,7 @@ bool AecDbX3dPart::GetActiveInf(CPoint& ptRC) const void AecDbX3dPart::RemoveAll3dSolidRec() { + m_bDirty = true; AcDbX3dSolid* pXSolid = NULL; for (int i = 0;i < m_arX3DSolidPtrsUnite.length();i++) { @@ -503,6 +508,7 @@ void AecDbX3dPart::RemoveAll3dSolidRec() void AecDbX3dPart::RemoveAt(int nIndex,AcDb::BoolOperType bType/* = AcDb::kBoolUnite*/,bool bForHouseSub/* = false*/) { + m_bDirty = true; AcDbX3dSolid* pXSolid = NULL; if (bForHouseSub) { @@ -581,6 +587,7 @@ AcDbX3dSolid* AecDbX3dPart::GetX3dSolid(int nIndex,AcDb::BoolOperType bType/* = bool AecDbX3dPart::SetAxis(int nIndex,const AcGeVector3d& vtAxis) { + m_bDirty = true; if (nIndex >= 0 && nIndex < MAX_AXISROTATS) { m_arVtAxis.setAt(nIndex,vtAxis); @@ -607,6 +614,7 @@ void AecDbX3dPart::SetHideShow( ) void AecDbX3dPart::SetHide(bool bHide) { + m_bDirty = true; m_mapXData.SetAt(_T("Hide"),bHide ? 1 : 0); } @@ -622,6 +630,7 @@ bool AecDbX3dPart::IsHide() const void AecDbX3dPart::PeelOffTheSkin(int nPos) { + m_bDirty = true; m_nPeelOff = nPos; if (m_pSolidDraw != NULL) @@ -638,11 +647,13 @@ bool AecDbX3dPart::IsPeelOffTheSkin() const void AecDbX3dPart::SetActive(bool bActive) { + m_bDirty = true; m_bActive = bActive; } void AecDbX3dPart::AddMove(const AcGeVector3d& vtMove) { + m_bDirty = true; m_vtMove += vtMove; if (m_pSolidDraw != NULL) @@ -654,6 +665,7 @@ void AecDbX3dPart::AddMove(const AcGeVector3d& vtMove) void AecDbX3dPart::AddMove(const AcGeMatrix3d& xMirror) { + m_bDirty = true; m_vtMove += xMirror.translation(); if (m_pSolidDraw != NULL) @@ -670,6 +682,7 @@ AcGeVector3d AecDbX3dPart::GetMove() const void AecDbX3dPart::ResetMove() { + m_bDirty = true; m_vtMove = AcGeVector3d::kIdentity; if (m_pSolidDraw != NULL) @@ -681,6 +694,7 @@ void AecDbX3dPart::ResetMove() void AecDbX3dPart::AddRotate(int nAxisIndex,double dRot) { + m_bDirty = true; if (nAxisIndex >= 0 && nAxisIndex <= MAX_AXISROTATS ) { m_dAxisRotats[nAxisIndex] += dRot; @@ -704,6 +718,7 @@ double AecDbX3dPart::GetRotate(int nAxisIndex) const void AecDbX3dPart::ResetRotate(int nAxisIndex) { + m_bDirty = true; if (nAxisIndex >= 0 && nAxisIndex < MAX_AXISROTATS) { m_dAxisRotats[nAxisIndex] = 0.0; @@ -765,6 +780,7 @@ void AecDbX3dPart::Transformby(AcGeVector3d& vt) const void AecDbX3dPart::SetBoolOperFor(int nOper) { + m_bDirty = true; m_nBoolOper = nOper; } @@ -785,6 +801,16 @@ const AecDbObjXDataMap* AecDbX3dPart::GetSpecialtyData() const bool AecDbX3dPart::Create() { + //显式调用一律重建:外部可能直接改过 x3dsolid(如对 GetX3dSolid(0) + //调 TransformBy 后再 Create),部件无法感知,只能无条件重算 + return Rebuild(); +} + +bool AecDbX3dPart::Rebuild() +{ + //先清标志再重建,避免构建过程中再次触发 EnsureCreated 造成递归 + m_bDirty = false; + if (m_pSolid != NULL) DELETE_PTR(m_pSolid); @@ -900,8 +926,18 @@ bool AecDbX3dPart::Create() return true; } +bool AecDbX3dPart::EnsureCreated() const +{ + if (!m_bDirty && m_pSolid != NULL) + return true; + + return const_cast(this)->Rebuild(); +} + int AecDbX3dPart::GetForHouseSubtract(AcDbVoidPtrArray& arSolidPtrs) const { + EnsureCreated(); + AcDbX3dSolid* pXSolid = NULL; AcGePoint3d ptOrg = m_ptOrg; @@ -939,6 +975,8 @@ int AecDbX3dPart::GetForHouseSubtract(AcDbVoidPtrArray& arSolidPtrs) const AcDb3dSolid* AecDbX3dPart::CreateDraw3dSolid() const { + EnsureCreated(); + AcDb3dSolid* pDraw = NULL; if (m_pSolid != NULL) { @@ -968,6 +1006,8 @@ Acad::ErrorStatus AecDbX3dPart::Draw2d(AcGiDraw &dc) const Acad::ErrorStatus AecDbX3dPart::Draw3d(AcGiDraw &dc) const { + EnsureCreated(); + if (m_pSolidDraw == NULL) { m_pSolidDraw = CreateDraw3dSolid(); @@ -1102,6 +1142,8 @@ Acad::ErrorStatus AecDbX3dPart::getOsnapPoints( AcDb::OsnapMode osnapMode, AcGePoint3dArray& snapPoints, AcDbIntArray& geomIds) const { + EnsureCreated(); + if (m_pSolidDraw != NULL) { m_pSolidDraw->getOsnapPoints(osnapMode,gsSelectionMark,pickPoint,lastPoint,viewXform,snapPoints,geomIds); @@ -1188,6 +1230,7 @@ Acad::ErrorStatus AecDbX3dPart::dwgInFields (AcDbDwgFiler* pFiler) pFiler->readBytes(m_dAxisRotats,sizeof(double) * MAX_AXISROTATS); m_mapXData.dwgInFields(pFiler); + m_bDirty = true; //开图时不建几何,首次绘制或取几何时再重建 return Acad::eOk; } @@ -1254,6 +1297,7 @@ Acad::ErrorStatus AecDbX3dPart::dwgOutFields(AcDbDwgFiler* pFiler) const Acad::ErrorStatus AecDbX3dPart::CopyFrom(AecDbX3dPart* pSrcPart) { + m_bDirty = true; if (pSrcPart == NULL) return Acad::eInvalidInput; diff --git a/SourceCode/Code2026/CoreLibrary/AecDbX3dPartEntity.cpp b/SourceCode/Code2026/CoreLibrary/AecDbX3dPartEntity.cpp index f2ec803..ccac833 100644 --- a/SourceCode/Code2026/CoreLibrary/AecDbX3dPartEntity.cpp +++ b/SourceCode/Code2026/CoreLibrary/AecDbX3dPartEntity.cpp @@ -1821,7 +1821,7 @@ Acad::ErrorStatus AecDbX3dPartEntity::dwgInFields (AcDbDwgFiler* pFiler) return (Acad::eMakeMeProxy) ; m_pPart->dwgInFields(pFiler); - m_pPart->Create(); + //开图时不建布尔结果:dwgInFields 里已置脏,首次绘制或取几何时由 EnsureCreated 重建 m_drawable2d.dwgInFields(pFiler, version); diff --git a/SourceCode/Code2026/inc/AecDbX3dPart.h b/SourceCode/Code2026/inc/AecDbX3dPart.h index 857c2dd..b695398 100644 --- a/SourceCode/Code2026/inc/AecDbX3dPart.h +++ b/SourceCode/Code2026/inc/AecDbX3dPart.h @@ -71,6 +71,7 @@ public: int GetBoolOperFor() const; bool Create(); + bool EnsureCreated() const; AcDb3dSolid* CreateDraw3dSolid() const; int GetForHouseSubtract(AcDbVoidPtrArray& arSolidPtrs) const; @@ -117,6 +118,8 @@ public: protected: + bool Rebuild(); //无条件重建布尔结果 + //序列化 CString m_sName; CString m_sGUID; @@ -138,6 +141,7 @@ protected: bool m_bActive; //活动状态 int m_nPeelOff; //是否需要剖开 AcDb3dSolid* m_pSolid; //原始solid元 + bool m_bDirty; //参数已变更,几何待重建 mutable AcDb3dSolid* m_pSolidDraw; //临时绘制solid元 mutable SHJson::WValue m_json; }; From 8ca95193208d36bc10c864d684864dcbd7e84852 Mon Sep 17 00:00:00 2001 From: company-desktop-computer Date: Thu, 22 Oct 2026 15:41:14 +0800 Subject: [PATCH 2/2] =?UTF-8?q?refactor:=20X3dPart=20=E7=9A=84=E6=87=92?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E6=A0=87=E5=BF=97=E6=94=B9=E5=90=8D=20m=5FbN?= =?UTF-8?q?eedCreate=20=E5=B9=B6=E5=8A=A0=20mutable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 与 AcDbX3dSolid::m_bNeedCreate 对齐:同一个语义(派生几何缓存失效, 首次使用时再算),用同一个名字,避免 m_bDirty 被理解成"参数没写完"。 声明为 mutable,与 AcDbX3dSolid 一致;清标志仍在 Rebuild() 里做。 --- .../Code2026/CoreLibrary/AecDbX3dPart.cpp | 40 +++++++++---------- SourceCode/Code2026/inc/AecDbX3dPart.h | 2 +- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/SourceCode/Code2026/CoreLibrary/AecDbX3dPart.cpp b/SourceCode/Code2026/CoreLibrary/AecDbX3dPart.cpp index ade4a5e..5958799 100644 --- a/SourceCode/Code2026/CoreLibrary/AecDbX3dPart.cpp +++ b/SourceCode/Code2026/CoreLibrary/AecDbX3dPart.cpp @@ -48,7 +48,7 @@ AecDbX3dPart::AecDbX3dPart(void) m_nBoolOper = 0; m_pSolidDraw = NULL; m_pSolid = NULL; - m_bDirty = true; + m_bNeedCreate = true; m_sName = _T(""); m_sGUID = IDCreate(); m_bActive = false; @@ -61,7 +61,7 @@ AecDbX3dPart::AecDbX3dPart(const AecDbX3dPart& pPart) { m_pSolidDraw = NULL; m_pSolid = NULL; - m_bDirty = true; + m_bNeedCreate = true; m_sName = pPart.m_sName; m_sGUID = pPart.m_sGUID; @@ -152,7 +152,7 @@ void AecDbX3dPart::ReCreateGUID() void AecDbX3dPart::AddX3dSolid(AcDbX3dSolid* pXSolid,AcDb::BoolOperType bType /*AcDb::kBoolUnite*/,bool bForHouseSub /*= false*/) { - m_bDirty = true; + m_bNeedCreate = true; if (bType == AcDb::kBoolUnite) { m_arX3DSolidPtrsUnite.append(pXSolid); @@ -172,7 +172,7 @@ void AecDbX3dPart::AddX3dSolid(AcDbX3dSolid* pXSolid,AcDb::BoolOperType bType / void AecDbX3dPart::SetOrgPoint(const AcGePoint3d& ptOrg) { - m_bDirty = true; + m_bNeedCreate = true; m_ptOrg = ptOrg; } @@ -471,7 +471,7 @@ bool AecDbX3dPart::GetActiveInf(CPoint& ptRC) const void AecDbX3dPart::RemoveAll3dSolidRec() { - m_bDirty = true; + m_bNeedCreate = true; AcDbX3dSolid* pXSolid = NULL; for (int i = 0;i < m_arX3DSolidPtrsUnite.length();i++) { @@ -508,7 +508,7 @@ void AecDbX3dPart::RemoveAll3dSolidRec() void AecDbX3dPart::RemoveAt(int nIndex,AcDb::BoolOperType bType/* = AcDb::kBoolUnite*/,bool bForHouseSub/* = false*/) { - m_bDirty = true; + m_bNeedCreate = true; AcDbX3dSolid* pXSolid = NULL; if (bForHouseSub) { @@ -587,7 +587,7 @@ AcDbX3dSolid* AecDbX3dPart::GetX3dSolid(int nIndex,AcDb::BoolOperType bType/* = bool AecDbX3dPart::SetAxis(int nIndex,const AcGeVector3d& vtAxis) { - m_bDirty = true; + m_bNeedCreate = true; if (nIndex >= 0 && nIndex < MAX_AXISROTATS) { m_arVtAxis.setAt(nIndex,vtAxis); @@ -614,7 +614,7 @@ void AecDbX3dPart::SetHideShow( ) void AecDbX3dPart::SetHide(bool bHide) { - m_bDirty = true; + m_bNeedCreate = true; m_mapXData.SetAt(_T("Hide"),bHide ? 1 : 0); } @@ -630,7 +630,7 @@ bool AecDbX3dPart::IsHide() const void AecDbX3dPart::PeelOffTheSkin(int nPos) { - m_bDirty = true; + m_bNeedCreate = true; m_nPeelOff = nPos; if (m_pSolidDraw != NULL) @@ -647,13 +647,13 @@ bool AecDbX3dPart::IsPeelOffTheSkin() const void AecDbX3dPart::SetActive(bool bActive) { - m_bDirty = true; + m_bNeedCreate = true; m_bActive = bActive; } void AecDbX3dPart::AddMove(const AcGeVector3d& vtMove) { - m_bDirty = true; + m_bNeedCreate = true; m_vtMove += vtMove; if (m_pSolidDraw != NULL) @@ -665,7 +665,7 @@ void AecDbX3dPart::AddMove(const AcGeVector3d& vtMove) void AecDbX3dPart::AddMove(const AcGeMatrix3d& xMirror) { - m_bDirty = true; + m_bNeedCreate = true; m_vtMove += xMirror.translation(); if (m_pSolidDraw != NULL) @@ -682,7 +682,7 @@ AcGeVector3d AecDbX3dPart::GetMove() const void AecDbX3dPart::ResetMove() { - m_bDirty = true; + m_bNeedCreate = true; m_vtMove = AcGeVector3d::kIdentity; if (m_pSolidDraw != NULL) @@ -694,7 +694,7 @@ void AecDbX3dPart::ResetMove() void AecDbX3dPart::AddRotate(int nAxisIndex,double dRot) { - m_bDirty = true; + m_bNeedCreate = true; if (nAxisIndex >= 0 && nAxisIndex <= MAX_AXISROTATS ) { m_dAxisRotats[nAxisIndex] += dRot; @@ -718,7 +718,7 @@ double AecDbX3dPart::GetRotate(int nAxisIndex) const void AecDbX3dPart::ResetRotate(int nAxisIndex) { - m_bDirty = true; + m_bNeedCreate = true; if (nAxisIndex >= 0 && nAxisIndex < MAX_AXISROTATS) { m_dAxisRotats[nAxisIndex] = 0.0; @@ -780,7 +780,7 @@ void AecDbX3dPart::Transformby(AcGeVector3d& vt) const void AecDbX3dPart::SetBoolOperFor(int nOper) { - m_bDirty = true; + m_bNeedCreate = true; m_nBoolOper = nOper; } @@ -809,7 +809,7 @@ bool AecDbX3dPart::Create() bool AecDbX3dPart::Rebuild() { //先清标志再重建,避免构建过程中再次触发 EnsureCreated 造成递归 - m_bDirty = false; + m_bNeedCreate = false; if (m_pSolid != NULL) DELETE_PTR(m_pSolid); @@ -928,7 +928,7 @@ bool AecDbX3dPart::Rebuild() bool AecDbX3dPart::EnsureCreated() const { - if (!m_bDirty && m_pSolid != NULL) + if (!m_bNeedCreate && m_pSolid != NULL) return true; return const_cast(this)->Rebuild(); @@ -1230,7 +1230,7 @@ Acad::ErrorStatus AecDbX3dPart::dwgInFields (AcDbDwgFiler* pFiler) pFiler->readBytes(m_dAxisRotats,sizeof(double) * MAX_AXISROTATS); m_mapXData.dwgInFields(pFiler); - m_bDirty = true; //开图时不建几何,首次绘制或取几何时再重建 + m_bNeedCreate = true; //开图时不建几何,首次绘制或取几何时再重建 return Acad::eOk; } @@ -1297,7 +1297,7 @@ Acad::ErrorStatus AecDbX3dPart::dwgOutFields(AcDbDwgFiler* pFiler) const Acad::ErrorStatus AecDbX3dPart::CopyFrom(AecDbX3dPart* pSrcPart) { - m_bDirty = true; + m_bNeedCreate = true; if (pSrcPart == NULL) return Acad::eInvalidInput; diff --git a/SourceCode/Code2026/inc/AecDbX3dPart.h b/SourceCode/Code2026/inc/AecDbX3dPart.h index b695398..f32b774 100644 --- a/SourceCode/Code2026/inc/AecDbX3dPart.h +++ b/SourceCode/Code2026/inc/AecDbX3dPart.h @@ -141,7 +141,7 @@ protected: bool m_bActive; //活动状态 int m_nPeelOff; //是否需要剖开 AcDb3dSolid* m_pSolid; //原始solid元 - bool m_bDirty; //参数已变更,几何待重建 + mutable bool m_bNeedCreate; //几何待重建,首次使用时再算 mutable AcDb3dSolid* m_pSolidDraw; //临时绘制solid元 mutable SHJson::WValue m_json; };