Files
envi-code/SourceCode/Code2026/inc/AecDbEntityCommon.h
T
gjm c84bc78869 重构底层
重构AecDbEntityBase,AecDbCurveBase
2026-10-19 09:19:05 +08:00

343 lines
12 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
// ============================================================================
// AecDbEntityCommon.h
//
// 自定义实体的公共基类。
//
// AecDbEntityBase : public AcDbEntity
// AecDbCurveBase : public AcDbCurve
//
// 两者是两条平行的根(AcDb 类不能虚继承),历史上是两份逐行复制的实现。
// 本类不继承任何 AcDb / ARX 类,只承载两条根中 AcDbEntity 虚函数那一层,
// 以及它们必须的依赖(显示缓存、显示模式、写使能、静态工具)。
//
// 约定:
// 1. 需要 AcDb 基类的实现时,直接 GetMe()->AcDbEntity::xxx(...) 限定调用,
// 不为「AcDbEntity:: 还是 AcDbCurve::」另立钩子。
// AcDbCurve 没有重写这些接口(dwgInFields / subList / saveAs / setTransparency /
// setColorIndex / subWblockClone … 都在 AcDbEntity),两者是同一个实现。
// 2. 两族行为有差异的函数,本类给默认实现并声明为 virtual,
// 由有差异的那一族 override。不用 bool 开关参数,也不合并行为。
// 3. 需要回到 AcDb 一侧操作时走 GetMe()。
// ============================================================================
#include "dbmain.h"
#include "AcGiDraw.h"
#include "AecSubDef.h"
#include "shJson.h"
#include "EarThwormDef.h"
#pragma warning(disable: 4275 4251)
// 与 AecDbEntityBase.h 相同的导出规则:AecRxBase 内部导出,其它模块导入。
// 用独立宏名,避免与 AECDLLIMPEXP 的定义顺序互相影响。
#ifdef AECRXBASE_EXPORT
#define AECCOMMON_DLLIMPEXP __declspec(dllexport)
#else
#define AECCOMMON_DLLIMPEXP __declspec(dllimport)
#endif
class AecDbObjXDataMap;
class AcGiViewDraw;
class AcGiExplodeDraw;
namespace SimpleProperty { struct PropertySetByIndex; struct PropertySetByName; }
#ifndef _ttof
#define _ttof(pszVal) _tcstod((pszVal), NULL)
#endif
class AECCOMMON_DLLIMPEXP AecDbEntityCommon
{
public:
AecDbEntityCommon(void);
virtual ~AecDbEntityCommon(void);
protected:
// 世界绘制:原 AecDbEntityBase::subWorldDraw / AecDbCurveBase::subWorldDraw
// 逐行一致。subWorldDraw 是 AcGiDrawable 的虚函数,本类不在 AcDb 继承链上,
// 只能由两个根各自留一行转发。
virtual Adesk::Boolean base_WorldDraw(AcGiWorldDraw* pWd);
// 视口绘制:原两个根的 subViewportDraw 逐行一致,同样只能由两个根转发。
virtual void base_ViewportDraw(AcGiViewportDraw* pMode);
// 视口绘制标志 / 绘制属性:原两个根逐行一致。
// 这两个接口在 AcDb 一侧是 protected,本类取不到,由两个根先调基类、
// 把基类结果作为 nBaseFlags 传进来,这里只负责叠加自己的标志位。
virtual Adesk::UInt32 base_ViewportDrawLogicalFlags(Adesk::UInt32 nBaseFlags);
virtual Adesk::UInt32 base_SetAttributes(Adesk::UInt32 nBaseFlags);
// 炸开:原两个根的 subExplode 逐行一致。
virtual Acad::ErrorStatus base_Explode(AcDbVoidPtrArray& entitySet) const;
// 保存代理实体图元:原两个根的 saveAs 逐行一致。
// 代理分支要回到具体实体自己的 subWorldDraw(子类可能重写),走 CallWorldDraw。
virtual void base_SaveAs(AcGiWorldDraw* pWd, AcDb::SaveType saveType);
// 几何范围:原两个根的 subGetGeomExtents 逐行一致。
virtual Acad::ErrorStatus base_GetGeomExtents(AcDbExtents& extents) const;
// 对象捕捉点(第一个重载):原两个根逐行一致。
virtual Acad::ErrorStatus base_GetOsnapPoints(AcDb::OsnapMode osnapMode,
INT_PTR gsSelectionMark,
const AcGePoint3d& ptPick,
const AcGePoint3d& lastPoint,
const AcGeMatrix3d& viewXform,
AcGePoint3dArray& snapPoints,
AcDbIntArray& geomIds) const;
virtual Acad::ErrorStatus base_DeepClone( AcDbObject* pOwnerObject,
AcDbObject*& pClonedObject,
AcDbIdMapping& idMap,
Adesk::Boolean isPrimary = Adesk::kTrue) const;
virtual Acad::ErrorStatus base_WblockClone( AcRxObject* pOwnerObject,
AcDbObject*& pClonedObject,
AcDbIdMapping& idMap,
Adesk::Boolean isPrimary = Adesk::kTrue) const;
// 桥:转调 AcDb 一侧原生的 subWblockClone(fast wblock 时用它交回基类)。
// subWblockClone 在 AcDbObject 里是 protected,本类不在继承链上,
// 只能由两个根各自转调,限定 AcDbEntity:: / AcDbCurve::。
virtual Acad::ErrorStatus CallAcDbWblockClone(AcRxObject* pOwnerObject,
AcDbObject*& pClonedObject,
AcDbIdMapping& idMap,
Adesk::Boolean isPrimary) const = 0;
// 桥:回到具体实体自己的 subWorldDraw(子类可能重写,saveAs 的代理分支要用)。
// subWorldDraw 在 AcGiDrawable 里是 protected,本类不在继承链上取不到。
virtual Adesk::Boolean CallWorldDraw(AcGiWorldDraw* pWd) = 0;
// ------------------------------------------------------------------
// 桥:由 AecDbEntityBase / AecDbCurveBase 实现
// ------------------------------------------------------------------
public:
// 回到 AcDb 一侧。两个根的 AcDb 根都是第一个基类,实现为 return this;
virtual AcDbEntity* GetMe() = 0;
virtual const AcDbEntity* GetMe() const = 0;
virtual bool IsThisMe(const AcDbEntity *pEnt) const = 0;
// 专业数据容器(两个根原本就是纯虚接口)
virtual AecDbObjXDataMap* GetSpecialtyData(AcDb::OpenMode bMode = AcDb::kForWrite) = 0;
virtual const AecDbObjXDataMap* GetSpecialtyData() const = 0;
//获取当前显示模式
int GetDrawDimCur() const;
// 得到实体唯一得名字,revit 通过这个字符串来判断是否有同样得实体
// 如果有,则在revit中可以生成一个族来替代这些同样得实体,以加快速度
virtual CString getUniqueName() const;
virtual void NewGUID() {}
virtual double GetArea() const {return .0;}
virtual void PreprocessForHlr( const AcGePoint3d &ptPlnO
, const AcGeVector3d &vtPlnN
, AcArray<AcDbEntity*> &ar) const;
/*
此函数只修改 ar内的实体的 图层、线型、颜色, 但线宽不处理
如有其他要求,重载
ar 是 hlr 通过调用实体的Draw3d函数得到的结果
preAr 中的 first(AcDbEntity*) 来自于 “PreprocessForHlr” 函数得到的实体指针
preAr 中的 second 来自于 first 经过 hlr 计算之后的结果
基类不处理 preAr
*/
virtual void ProcessHlrResult(const AcArray<AcDbEntity*> &ar
, const std::map<AcDbEntity*, AcArray<AcDbEntity*>> &preAr
, AcArray<AcDbEntity*> &output ) const;
virtual bool GetBimInfoTip(CString& sInfoTip) const;
// 为方便用户查询实体的属性,可以重载此函数,目前,此函数使用在“实体快速选择”功能上
virtual bool GetProperties(SimpleProperty::PropertySetByIndex &porpertys) const;
virtual bool SetProperties(SimpleProperty::PropertySetByName &porpertys);
// 导出json
virtual SHJson::WValue& ToJson(bool bExprotGeo = true) const;
// 通过json创建
virtual bool ByJson(const SHJson::WValue &v);
//获取体积
virtual double GetVolume(bool bIsBody = false) const;
virtual void SetActive(bool bActive) {};
virtual bool IsActive() const { return false; }
protected:
// 子类真正实现的绘制入口(两个根的默认实现都是 return eOk)
virtual Acad::ErrorStatus Draw2d(AcGiDraw& dc) const;
virtual Acad::ErrorStatus Draw3d(AcGiDraw& dc) const;
virtual void AssertWriteEnabled(Adesk::Boolean autoUndo = true, Adesk::Boolean recordModified = true);
protected:
static int GetDrawMode();
static void SetDrawMode(int nMode);
static void BackupColorIndex(AcDbEntity* pEnt);
static int SetBackupColorIndex(AcDbEntity* pEnt);
//获取炸碎2D/3d模式
int GetExplodeMode() const;
//获取显示维度 0--NONE; 1--2D; 2--3D; 3--2D&3D
int GetDrawDimOnType(int nDrawMode, int nDrawType) const;
//2023-6-26 增加单击夹点发送命令DBL_DXF
virtual bool GetPositionGrip(int nIndex, AecGripData *&pGrip) const { return NULL; }
bool SubAddHitEditGrip(AcDbGripDataPtrArray &grips) const;
bool HitOnGripEdit(const AcDbVoidPtrArray &gripAppData);
public:
// 2d 缓存操作
virtual bool Draw2DBuffers(AcGiDraw &dc) const;
const AcDbVoidPtrArray& Get2DBuffer()const;
bool Has2DBuffer()const;
void Add2DBuffer(AcDbEntity *pEnt)const;
void Add2DBuffer(const AcDbVoidPtrArray &arr)const;
bool IsIn2DBuffer(AcDbEntity* pEnt) const;
void Clean2DBuffer()const;
void Clean2DBufferNoDel()const;
// 3d 缓存操作
bool Draw3DBuffers(AcGiDraw &dc) const;
const AcDbVoidPtrArray &Get3DBuffer()const;
bool Has3DBuffer()const;
void Add3DBuffer(AcDbEntity *pEnt)const;
void Add3DBuffer(const AcDbVoidPtrArray &arr)const;
bool IsIn3DBuffer(AcDbEntity *pEnt) const;
void Clean3DBuffer()const;
void Clean3DBufferNoDel()const;
Acad::ErrorStatus ReCreateDraw2d();
Acad::ErrorStatus ReCreateDraw3d();
//获取二维视图显示的图形
virtual int GetDraw2dables(Adesk::UInt16 nDrawStyle, AcDbVoidPtrArray &arEntPtrs) const;
//获取三维显示图形
virtual int GetDraw3dables(AcDbVoidPtrArray &arEntPtrs, bool bWriteBimInfo = false) const;
//用户级别的数据调用消息
virtual bool SendUserData(struct resbuf *pRb) { return false; }
virtual int GetSectionDraw(const AcGePoint3d &ptFr
, const AcGePoint3d &ptTo
, const AcGeVector3d &vtViewDir
, const AcGeVector3d &vtTo
, AcDbVoidPtrArray &arRegionPtrs) const { return 0; }
virtual AcDb3dSolid *GetBlackHole() const { return NULL; }
//剖切提取
bool GetSectionHatchPattern(CString& sPattern) const;
void BoolSubtractHide() const;
Acad::ErrorStatus subGet3dGeomExtents(AcDbExtents &extents) const;
void Add3DBoolSubtract(AcDb3dSolid* pSolidBlackHole);
void Remove3DBoolSubtract();
void AddBlackHole(AcDbObjectId& idHole);
void RemoveBlackHole(AcDbObjectId& idHole);
void DrawBlackHole(AcDbEntity* pSolidEnt) const;
void UpdateDrableSpecData(LPCTSTR pszApp,LPCTSTR pszKey,CString& sVal);
//按分隔符拆字符串(CoreLibrary / PipelineCmd 等多处按 AecDbEntityBase:: 限定调用)
static void SplitStrintToArray(LPCTSTR pszDescr, CStringArray & arInfo, TCHAR tcSpace);
protected:
// 绘制函数被调用的方式(WorldDraw / ViewportDraw / Explode)
// mutable:subExplode 是 const 函数,原实现靠 const_cast 写入
mutable ExplodeOrDrawType m_eExplodeOrDrawType;
// 最近一次实际绘制的是 2D / 3D(-1 表示尚未绘制)
short m_nDrawDimCur;
// 2D / 3D 显示缓存
mutable AcDbVoidPtrArray m_ar2DDrableBufPtrs_;//临时缓存 俯视图
mutable AcDbVoidPtrArray m_ar3DDrableBufPtrs_;//临时缓存
private:
mutable SHJson::WValue m_json;
public:
template<typename T>
BOOL GetAt(LPCTSTR pszKey, T &va) const
{
const AecDbObjXDataMap *pMap(GetSpecialtyData());
if (!pMap) return FALSE;
return pMap->GetAt(pszKey, va);
}
template<typename T1, typename T2>
BOOL GetAt(LPCTSTR pszKey, T1 va1, T2 va2) const
{
const AecDbObjXDataMap *pMap(GetSpecialtyData());
if (!pMap) return FALSE;
return pMap->GetAt(pszKey, va1, va2);
}
template <int N>
BOOL GetAt(LPCTSTR pszKey, TCHAR(&va)[N]) const
{
const AecDbObjXDataMap *pMap(GetSpecialtyData());
if (!pMap) return FALSE;
CString s;
if (pMap->GetAt(pszKey, s) == FALSE) return FALSE;
_tcsncpy_s(va, N, s, N - 1);
return TRUE;
}
template <int N>
BOOL GetAt(LPCTSTR pszKey, LPTSTR va) const
{
const AecDbObjXDataMap *pMap(GetSpecialtyData());
if (!pMap) return FALSE;
CString s;
if (pMap->GetAt(pszKey, s) == FALSE) return FALSE;
_tcsncpy_s(va, N, s, N - 1);
return TRUE;
}
template<typename T>
BOOL SetAt(LPCTSTR pszKey, T va)
{
AecDbObjXDataMap *pMap(GetSpecialtyData(AcDb::kForWrite));
if (!pMap) return FALSE;
return pMap->SetAt(pszKey, va);
}
template<typename T1, typename T2>
BOOL SetAt(LPCTSTR pszKey, T1 va1, T2 va2)
{
AecDbObjXDataMap *pMap(GetSpecialtyData(AcDb::kForWrite));
if (!pMap) return FALSE;
return pMap->SetAt(pszKey, va1, va2);
}
template <class K> static BOOL CopyObject(const K &src, K &dest)
{
AcDbDeepCloneFiler filer;
BOOL bRet = FALSE;
if (src.dwgOutFields(&filer) == Acad::eOk)
{
filer.seek(0L, 0);
bRet = (dest.dwgInFields(&filer) == Acad::eOk);
}
return bRet;
}
};