Files
envi-code/SourceCode/Code2026/inc/AecDbX3dPart.h
T
company-desktop-computer 5a5cd08721 perf: X3dPart 布尔结果改为按需重建,开图不再逐件建体
方案 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 补回。
2026-10-22 15:07:18 +08:00

148 lines
4.2 KiB
C++

#pragma once
#ifdef EARTHWORM_EXPORT
#define DLLIMPEXP __declspec(dllexport)
#else
#define DLLIMPEXP __declspec(dllimport)
#endif
#ifndef MAX_AXISROTATS
#define MAX_AXISROTATS 16
#endif
#include "AcDbX3dSolid.h"
#include "AecDbObjXDataMap.h"
class AcDbX3dSolid;
class DLLIMPEXP AecDbX3dPart
{
public:
AecDbX3dPart(void);
AecDbX3dPart(const AecDbX3dPart& pPart);
~AecDbX3dPart(void);
static Adesk::UInt32 kCurrentVersionNumber;
void SetName(LPCTSTR pszName);
void GetName(CString& sName) const;
LPCTSTR GetGUID() const;
void ReCreateGUID();
//添加基本单元
void AddX3dSolid(AcDbX3dSolid* pXSolid,AcDb::BoolOperType bType = AcDb::kBoolUnite,bool bForHouseSub = false);
void RemoveAt(int nIndex,AcDb::BoolOperType bType = AcDb::kBoolUnite,bool bForHouseSub = false );
void RemoveAll3dSolidRec();
int GetX3dSolidCount(AcDb::BoolOperType bType = AcDb::kBoolUnite,bool bForHouseSub = false) const;
AcDbX3dSolid* GetX3dSolid(int nIndex,AcDb::BoolOperType bType = AcDb::kBoolUnite) const;
void SetOrgPoint(const AcGePoint3d& ptOrg);
AcGePoint3d GetOrgPoint(bool bByTransform = false) const;
bool SetAxis(int nIndex,const AcGeVector3d& vtAxis);
bool GetAxis(int nIndex,AcGeVector3d& vtAxis) const;
void SetHide(bool bHide);
void SetHideShow( );
bool IsHide() const;
void PeelOffTheSkin(int nPos);
bool IsPeelOffTheSkin() const;
void SetActive(bool bActive);
//移动
void AddMove(const AcGeVector3d& vtMove);
void AddMove(const AcGeMatrix3d& xMirror);
AcGeVector3d GetMove() const;
void ResetMove();
//旋转
void AddRotate(int nAxisIndex,double dRot);
double GetRotate(int nAxisIndex) const;
void ResetRotate(int nAxisIndex);
void Transformby(AcGePoint3d& pt) const;
void Transformby(AcGeVector3d& vt) const;
void SetBoolOperFor(int nOper);
int GetBoolOperFor() const;
bool Create();
bool EnsureCreated() const;
AcDb3dSolid* CreateDraw3dSolid() const;
int GetForHouseSubtract(AcDbVoidPtrArray& arSolidPtrs) const;
int GetActiveInf() const;
void SetActiveInf(int nIndex);
//开孔的接口提取
bool GetInterface(int nIndex,AecInterface& inf) const;
bool GetInterface(int nRow,int nCol,AecInterface& inf) const;
bool GetInterfaceCount(CPoint& ptRC) const;
bool SetActiveInf(const CPoint& ptRC);
bool GetActiveInf(CPoint& ptRC) const;
Acad::ErrorStatus Draw2d(AcGiDraw &dc) const;
Acad::ErrorStatus Draw3d(AcGiDraw &dc) const;
Acad::ErrorStatus DrawAxis(AcGiDraw &dc) const;
Acad::ErrorStatus DrawInf(AcGiDraw &dc) const;
bool GetSlicePlan(AcGePlane& plan) const;
// 专业数据
AecDbObjXDataMap* GetSpecialtyData();
const AecDbObjXDataMap* GetSpecialtyData() const;
Acad::ErrorStatus getOsnapPoints( AcDb::OsnapMode osnapMode,
INT_PTR gsSelectionMark,
const AcGePoint3d& pickPoint,
const AcGePoint3d& lastPoint,
const AcGeMatrix3d& viewXform,
AcGePoint3dArray& snapPoints,
AcDbIntArray& geomIds) const;
Acad::ErrorStatus dwgInFields (AcDbDwgFiler* pFiler);
Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* pFiler) const;
Acad::ErrorStatus CopyFrom(AecDbX3dPart* pSrcPart);
void List() const;
SHJson::WValue& ToJson() const;
bool ByJson(const SHJson::WValue &v);
void setBimDatas(const SH_BIM_BLOCK &bims);
void getBimDatas(SH_BIM_BLOCK &bims);
protected:
bool Rebuild(); //无条件重建布尔结果
//序列化
CString m_sName;
CString m_sGUID;
Adesk::Int32 m_nBoolOper; //
AcDbVoidPtrArray m_arX3DSolidPtrsUnite;
AcDbVoidPtrArray m_arX3DSolidPtrsSubtr;
AcDbVoidPtrArray m_arX3DSolidPtrsSubtrForHouse;
//先旋转,后移动
AcGeVector3d m_vtMove; //总移动
AcGePoint3d m_ptOrg; //原点
AcGeVector3dArray m_arVtAxis; //轴向
double m_dAxisRotats[MAX_AXISROTATS];//最多10个轴向旋转
AecDbObjXDataMap m_mapXData; //BIM数据
//显示,临时
CPoint m_ptActiveInf; //开孔的活动接口索引行x列 不序列化
bool m_bActive; //活动状态
int m_nPeelOff; //是否需要剖开
AcDb3dSolid* m_pSolid; //原始solid元
bool m_bDirty; //参数已变更,几何待重建
mutable AcDb3dSolid* m_pSolidDraw; //临时绘制solid元
mutable SHJson::WValue m_json;
};