343 lines
12 KiB
C++
343 lines
12 KiB
C++
#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;
|
||
}
|
||
};
|