说明: 此次绘制的CAD自定义实体是一个矩形,具有拉伸功能。因为初次接触自定义实体,在一次次制作的过程中遇到了很多困难,幸好有老大和同事的帮助,当然还有广大网友们的文章协助,才完成了这个自定义实体的绘制。我不敢说到目前还会有什么问题,但希望能帮助到别人。

一、需要重载的函数

    //绘制夹点virtual Acad::ErrorStatus getGripPoints(AcDbGripDataPtrArray& grips, const double curViewUnitSize, const int gripSize, const AcGeVector3d& curViewDir, const int bitflags) const;//移动夹点virtual Acad::ErrorStatus moveGripPointsAt(const AcDbVoidPtrArray& gripAppData,const AcGeVector3d& offset,const int bitflags);//加载数据virtual Acad::ErrorStatus dwgInFields(AcDbDwgFiler* pFiler);//保存数据virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* pFiler) const;//矩阵转换virtual Acad::ErrorStatus transformBy(const AcGeMatrix3d& xform);//分解(炸开)virtual Acad::ErrorStatus explode(ZcDbVoidPtrArray& entitySet) const;//夹点状态virtual void gripStatus(const AcDb::GripStat status);//实体绘制virtual Adesk::Boolean worldDraw(AcGiWorldDraw* pWd);//捕捉点virtual Acad::ErrorStatus getOsnapPoints(AcDb::OsnapMode osnapMode, Adesk::GsMarker gsSelectionMark, const AcGePoint3d& pickPoint, const AcGePoint3d& lastPoint,const AcGeMatrix3d& viewXform, AcGePoint3dArray& snapPoints, AcDbIntArray & geomIds) const;//外包矩形virtual Acad::ErrorStatus getGeomExtents(AcDbExtents& extents) const;//删除virtual Acad::ErrorStatus erase(Adesk::Boolean erasing = true);

二、成员变量

因为这个自定义实体是矩形,所以是由四个直线组成,且由三个夹点。

 AcDbLine m_lineHori1;AcDbLine m_lineHori2;AcDbLine m_lineVert1;AcDbLine m_lineVert2;AcGePoint3d m_ptBase;       AcGePoint3d m_ptRight;  AcGePoint3d m_ptTop;

所以在写重载函数时,每个直线实体都要写一下。例如在worldDraw函数:

Adesk::Boolean CDiBanCsm::worldDraw(AcGiWorldDraw* pWd)
{assertReadEnabled();m_lineHori1.worldDraw(pWd);m_lineHori2.worldDraw(pWd);m_lineVert1.worldDraw(pWd);m_lineVert2.worldDraw(pWd);return Adesk::kTrue;
}

因为有夹点这个成员变量,所以,在dwgInFields函数、dwgOutFields函数、transformBy函数中也要将夹点添加进去:

Acad::ErrorStatus CDiBanCsm::dwgInFields(AcDbDwgFiler* pFiler)
{assertWriteEnabled();AcDbEntity::dwgInFields(pFiler);m_lineHori1.dwgInFields(pFiler);m_lineHori2.dwgInFields(pFiler);m_lineVert1.dwgInFields(pFiler);m_lineVert2.dwgInFields(pFiler);pFiler->readPoint3d(&m_ptBase);pFiler->readPoint3d(&m_ptRight);pFiler->readPoint3d(&m_ptTop);return pFiler->filerStatus();
}

三、夹点绘制

绘制夹点比较麻烦,如果你不是要绘制夹点的形状,可以重载

Acad::ErrorStatus getGripPoints(AcGePoint3dArray& gripPoints, AcDbIntArray & osnapModes, AcDbIntArray & geomIds
) const;

只需要在gripPoints参数中添加夹点坐标就可以,夹点为默认夹点。
这里,我们需要改变夹点的形状,所以这里我们需要绘制夹点。夹点用AcDbGripData类绘制,它是new出来的,所以我们需要将它delete。
我们需要重载gripStatus函数,在AcDb::kGripsDone状态下,将new的AcDbGripData指针delte。
我们要声明一个全局的map变量来存放AcDbGripData指针:

//键:自定义实体指针       值:AcDbGripData指针数组
static std::map<const AcDbEntity*, AcDbGripDataPtrArray> s_mapGripPtr;

直接上代码了:

Acad::ErrorStatus CDiBanCsm::getGripPoints(AcDbGripDataPtrArray& grips, const double curViewUnitSize, const int gripSize, const AcGeVector3d& curViewDir, const int bitflags) const
{assertReadEnabled();std::vector<CString>::const_iterator appIter = GetGripName();//这里appIter是一个字符串容器,存放的是夹点名称AcDbGripDataPtrArray tempGripArr;//BasePtAcDbGripData* pGripBase = new AcDbGripData();pGripBase->setAppData((void*)&(*appIter));//将夹点名称设置到数据中pGripBase->setGripPoint(m_ptBase);//设置夹点坐标grips.append(pGripBase);tempGripArr.append(pGripBase);appIter++;//RightPtAcDbGripData* pGripRight = new AcDbGripData();pGripRight->setAppData((void*)&(*appIter));pGripRight->setGripPoint(m_ptRight);pGripRight->setWorldDraw(DrawStretchGrip);grips.append(pGripRight);tempGripArr.append(pGripRight);appIter++;//TopPtAcDbGripData* pGripTop = new AcDbGripData();pGripTop->setAppData((void*)&(*appIter));pGripTop->setGripPoint(m_ptTop);pGripTop->setWorldDraw(DrawStretchGrip);grips.append(pGripTop);tempGripArr.append(pGripTop);appIter++;auto a = this;CCustomBase::s_mapGripPtr[this] = tempGripArr;//将new出来的AcDbGripData指针添加到s_mapGripPtr变量中return Acad::eOk;
}bool CDiBanCsm::DrawStretchGrip(AcDbGripData *pThis, AcGiWorldDraw *pWd, const AcDbObjectId& entId, AcDbGripOperations::DrawType type, AcGePoint3d *cursor, double dGripSize)
{dGripSize *= CCustomBase::s_gripSize / 2;//夹点的大小 CCustomBase::s_gripSize == 2.8AcGePoint3d  pt = pThis->gripPoint();CString* pStr = (CString*)(pThis->appData());AcGeVector3d vec = AcGeVector3d::kXAxis;AcDbObjectPointer<CDiBanCsm> m_pDiBan(entId, AcDb::kForRead);if (m_pDiBan.openStatus() != Acad::eOk)return false;if (*pStr == _T("RightPt"))vec = m_pDiBan->GetHoriDirection().normal();//得到实体的水平向量,这个接口自己写,通过直线的两点坐标else if (*pStr == _T("TopPt"))vec = m_pDiBan->GetVertDirection().normal();//得到实体的垂直向量auto vecUp = AcGeVector3d::kZAxis.crossProduct(vec).normal();AcGePoint3d pts[3];pts[0] = pt + vec * dGripSize;pts[1] = pt - vec * dGripSize / 2 + vecUp * dGripSize * .7;pts[2] = pt - vec * dGripSize / 2 - vecUp * dGripSize * .7;pWd->subEntityTraits().setFillType(kAcGiFillAlways);pWd->geometry().polygon(3, pts);return true;
}

在重载的gripStatus函数中delete夹点指针

void CDiBanCsm::gripStatus(const AcDb::GripStat status)
{AcDbEntity::gripStatus(status);switch (status){case AcDb::kGripsDone:CCustomBase::DeleteGrip(this);break;case AcDb::kGripsToBeDeleted:break;case AcDb::kDimDataToBeDeleted:break;}
}bool CCustomBase::DeleteGrip(const AcDbEntity* pEnt)
{std::map<const AcDbEntity*, AcDbGripDataPtrArray>::iterator iter;for (iter = s_mapGripPtr.begin(); iter != s_mapGripPtr.end(); iter++){if (pEnt == iter->first){AcDbGripDataPtrArray tempGripArr = iter->second;for (int i = 0; i < tempGripArr.length(); ++i){DEL(tempGripArr[i]);//这里delete 指针tempGripArr[i] = NULL;}}}int n = CCustomBase::s_mapGripPtr.erase(pEnt);//如果删除了会返回1,否则返回0  return n;
}

移动夹点就比较简单了,重写moveGripPointsAt函数就可以了

Acad::ErrorStatus CDiBanCsm::moveGripPointsAt(const AcDbVoidPtrArray& gripAppData,const AcGeVector3d& offset,
const int bitflags)
{assertWriteEnabled();CString* pStrTemp = NULL;for (int i = 0; i < gripAppData.length(); i++){pStrTemp = static_cast<CString*>(gripAppData[i]);if (*pStrTemp == _T("BasePt"))//通过点的名称,判断移动的是哪个夹点{//这里我是通过偏移向量,来移动直线的两点位置SetLinePoint(m_lineHori1, 3, offset);SetLinePoint(m_lineHori2, 3, offset);SetLinePoint(m_lineVert1, 3, offset);SetLinePoint(m_lineVert2, 3, offset);m_ptBase = GetBaseGripPt();//重新定义夹点的位置m_ptRight = GetRightGripPt();m_ptTop = GetTopGripPt();}else if (*pStrTemp == _T("RightPt")){AcGePoint3d ptStart = m_lineHori2.startPoint();AcGePoint3d ptEnd = m_lineHori2.endPoint();AcGeVector3d vctHori = ptEnd - ptStart;AcGeVector3d vctOffset = GetProjectVector(m_ptBase, offset, vctHori);SetLinePoint(m_lineHori1,2,vctOffset);SetLinePoint(m_lineHori2, 2, vctOffset);SetLinePoint(m_lineVert2, 3, vctOffset);m_ptBase = GetBaseGripPt();m_ptRight = GetRightGripPt();m_ptTop = GetTopGripPt();}else if (*pStrTemp == _T("TopPt")){AcGePoint3d ptStart = m_lineVert1.startPoint();AcGePoint3d ptEnd = m_lineVert1.endPoint();AcGeVector3d vctHori = ptEnd - ptStart;AcGeVector3d vctOffset = GetProjectVector(m_ptBase, offset, vctHori);SetLinePoint(m_lineVert1, 2, vctOffset);SetLinePoint(m_lineVert2, 2, vctOffset);SetLinePoint(m_lineHori1, 3, vctOffset);m_ptBase = GetBaseGripPt();m_ptRight = GetRightGripPt();m_ptTop = GetTopGripPt();}}return Acad::eOk;
}AcGeVector3d CCustomBase::GetProjectVector(const AcGePoint3d& ptBase, const AcGeVector3d& vctOffset, const AcGeVector3d& vctDirection)
{//得到某一向量在指定向量上的投影向量AcGePoint3d ptOffset = ptBase + vctOffset;AcGeLine3d geLine(ptBase, vctDirection);AcGePoint3d ptTarget = geLine.closestPointTo(ptOffset);return ptTarget - ptBase;
}

四、实体分解

需要重写explode函数,这里有两个知识要说,一个是如果自定义实体可以分解,需要添加克隆的直线指针

Acad::ErrorStatus CDiBanCsm::explode(ZcDbVoidPtrArray& entitySet) const
{assertReadEnabled();entitySet.append(m_lineHori1.clone());entitySet.append(m_lineHori2.clone());entitySet.append(m_lineVert1.clone());entitySet.append(m_lineVert2.clone());return Acad::eOk;
}

如果你想让自定义实体不能分解,返回值返回:Acad::eCannotExplodeEntity即可。

五、总结

其实原本的代码比这个多很多,这里我只是截取了重要部分展示。这是目前绘制的自定义实体,某些地方还需要改进。

六、源码展示

这篇文章本来是已经删掉的,因为我觉得自己写的这个自定义实体比较垃圾,但是删掉后发现别人还是能看,也能收到评论,就感觉许多人都有这个自定义实体这个需求的,今天准备把源码贴出来。在这里我要简单说明一下,这篇文章是当初学习ObjectArx自定义实体时写的,例子也是当时写的。主要功能实现是做了一个矩形自定义实体,这个实体选中后会显示三个夹点,实体位置夹点、向上拉伸夹点、向右拉伸夹点,且具有移动和拉伸功能。当时测试过,应该是没什么问题的,如果有问题的话也不要@我了。总共2个类,4个文件。

CCustomBase.h

#pragma once/*
//自定义实体初始化
CDiBanCsm::rxInit();
acrxBuildClassHierarchy();
//自定义实体删除
deleteAcRxClass(CDiBanCsm::desc());
*///自定义实体基类
class CCustomBase :public AcDbEntity
{public:CCustomBase();~CCustomBase();virtual Adesk::Boolean worldDraw(AcGiWorldDraw* pWd);virtual Acad::ErrorStatus dwgInFields(AcDbDwgFiler* pFiler);virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* pFiler) const;virtual Acad::ErrorStatus dxfInFields(AcDbDxfFiler* pFiler);virtual Acad::ErrorStatus dxfOutFields(AcDbDxfFiler* pFiler) const;virtual Acad::ErrorStatus getOsnapPoints(AcDb::OsnapMode osnapMode, Adesk::GsMarker gsSelectionMark, const AcGePoint3d& pickPoint, const AcGePoint3d& lastPoint,const AcGeMatrix3d& viewXform, AcGePoint3dArray& snapPoints, AcDbIntArray & geomIds) const;virtual Acad::ErrorStatus getGeomExtents(AcDbExtents& extents) const;virtual Acad::ErrorStatus transformBy(const AcGeMatrix3d& xform);virtual Acad::ErrorStatus getTransformedCopy(const AcGeMatrix3d& xform, AcDbEntity*& ent) const;virtual Acad::ErrorStatus erase(Adesk::Boolean erasing = true);protected:
#pragma region 辅助函数std::vector<CString>::const_iterator GetGripName() const;//记录夹点的名称//************************************// Summary:    得到X轴或Y轴偏移点后的点坐标// Parameters:   //    ptBase        -   输入要偏移的点坐标//    dX       -   输入X轴偏移距离//    dY        -   输入Y轴偏移距离// Returns:     //************************************AcGePoint3d GetOffsetPt(const AcGePoint3d& ptBase, double dX, double dY);//************************************// Summary:    得到某一向量在指定向量上的投影向量// Parameters:     //    ptBase        -   输入两个向量的交点//    vctOffset        -   输入某一向量//    vctDirection        -   输入指定向量// Returns:       //************************************AcGeVector3d GetProjectVector(const AcGePoint3d& ptBase, const AcGeVector3d& vctOffset, const AcGeVector3d& vctDirection);//************************************// Summary:   通过偏移向量移动直线的点坐标// Parameters:    //    pLine     -   输入直线指针//    nType       -   输入类型(1:移动起点,2:移动终点,3:都移动)//    vctOffset       -   输入偏移向量// Returns:       //************************************void SetLinePoint(AcDbLine& line, int nType, const AcGeVector3d& vctOffset);//设置直线偏移点#pragma endregion 辅助函数#pragma region 夹点
public:static double s_gripSize;    //夹点的大小static std::map<const AcDbEntity*, AcDbGripDataPtrArray> s_mapGripPtr;//delete夹点static bool DeleteGrip(const AcDbEntity* pEnt);
#pragma endregion 夹点protected:AcArray<AcDbEntity*> m_arrEntPtr;std::vector<CString> m_vecGripName;
};

CCustomBase.cpp

#include "StdAfx.h"
#include "CCustomBase.h"
#include <strsafe.h>double CCustomBase::s_gripSize = 2.8;
std::map<const AcDbEntity*, AcDbGripDataPtrArray> CCustomBase::s_mapGripPtr;CCustomBase::CCustomBase()
{}CCustomBase::~CCustomBase()
{}Adesk::Boolean CCustomBase::worldDraw(AcGiWorldDraw* pWd)
{assertReadEnabled();for (int i = 0; i < m_arrEntPtr.length(); ++i){m_arrEntPtr[i]->worldDraw(pWd);}return Adesk::kTrue;
}Acad::ErrorStatus CCustomBase::dwgInFields(AcDbDwgFiler* pFiler)
{//读取数据assertWriteEnabled();AcDbEntity::dwgInFields(pFiler);for (int i = 0; i < m_arrEntPtr.length(); ++i){m_arrEntPtr[i]->dwgInFields(pFiler);}return pFiler->filerStatus();
}Acad::ErrorStatus CCustomBase::dwgOutFields(AcDbDwgFiler* pFiler) const
{//存入数据assertReadEnabled();AcDbEntity::dwgOutFields(pFiler);for (int i = 0; i < m_arrEntPtr.length(); ++i){m_arrEntPtr[i]->dwgOutFields(pFiler);}return pFiler->filerStatus();
}Acad::ErrorStatus CCustomBase::dxfInFields(AcDbDxfFiler* pFiler)
{return Acad::eNotImplementedYet;
}Acad::ErrorStatus CCustomBase::dxfOutFields(AcDbDxfFiler* pFiler) const
{return Acad::eNotImplementedYet;
}Acad::ErrorStatus CCustomBase::getOsnapPoints(AcDb::OsnapMode osnapMode, Adesk::GsMarker gsSelectionMark, const AcGePoint3d& pickPoint, const AcGePoint3d& lastPoint, const AcGeMatrix3d& viewXform, AcGePoint3dArray& snapPoints, AcDbIntArray & geomIds) const
{assertReadEnabled();for (int i = 0; i < m_arrEntPtr.length(); ++i){m_arrEntPtr[i]->getOsnapPoints(osnapMode, gsSelectionMark, pickPoint, lastPoint, viewXform, snapPoints, geomIds);}return Acad::eOk;
}Acad::ErrorStatus CCustomBase::getGeomExtents(AcDbExtents& extents) const
{assertReadEnabled();for (int i = 0; i < m_arrEntPtr.length(); ++i){AcDbExtents ext;m_arrEntPtr[i]->getGeomExtents(ext);extents.addExt(ext);}return Acad::eOk;
}Acad::ErrorStatus CCustomBase::transformBy(const AcGeMatrix3d& xform)
{assertWriteEnabled();for (int i = 0; i < m_arrEntPtr.length(); ++i){m_arrEntPtr[i]->transformBy(xform);}return AcDbEntity::transformBy(xform);
}Acad::ErrorStatus CCustomBase::getTransformedCopy(const AcGeMatrix3d& xform, AcDbEntity*& ent) const
{assertReadEnabled();for (int i = 0; i < m_arrEntPtr.length(); ++i){m_arrEntPtr[i]->getTransformedCopy(xform, ent);}return AcDbEntity::getTransformedCopy(xform, ent);
}Acad::ErrorStatus CCustomBase::erase(Adesk::Boolean erasing /*= true*/)
{assertWriteEnabled();for (int i = 0; i < m_arrEntPtr.length(); ++i){m_arrEntPtr[i]->erase(erasing);}return Acad::eOk;
}std::vector<CString>::const_iterator CCustomBase::GetGripName() const
{return m_vecGripName.begin();
}AcGePoint3d CCustomBase::GetOffsetPt(const AcGePoint3d& ptBase, double dX, double dY)
{AcGePoint3d ptTemp = ptBase;ptTemp.x += dX;ptTemp.y += dY;return ptTemp;
}AcGeVector3d CCustomBase::GetProjectVector(const AcGePoint3d& ptBase, const AcGeVector3d& vctOffset, const AcGeVector3d& vctDirection)
{AcGePoint3d ptOffset = ptBase + vctOffset;AcGeLine3d geLine(ptBase, vctDirection);AcGePoint3d ptTarget = geLine.closestPointTo(ptOffset);return ptTarget - ptBase;
}void CCustomBase::SetLinePoint(AcDbLine& line, int nType, const AcGeVector3d& vctOffset)
{AcGePoint3d ptStart = line.startPoint();AcGePoint3d ptEnd = line.endPoint();switch (nType){case 1://移动起点ptStart += vctOffset;line.setStartPoint(ptStart);break;case 2://移动终点ptEnd += vctOffset;line.setEndPoint(ptEnd);break;case 3://移动起点和终点ptStart += vctOffset;line.setStartPoint(ptStart);ptEnd += vctOffset;line.setEndPoint(ptEnd);break;default:break;}
}bool CCustomBase::DeleteGrip(const AcDbEntity* pEnt)
{std::map<const AcDbEntity*, AcDbGripDataPtrArray>::iterator iter;for (iter = s_mapGripPtr.begin(); iter != s_mapGripPtr.end(); iter++){if (pEnt == iter->first){AcDbGripDataPtrArray tempGripArr = iter->second;for (int i = 0; i < tempGripArr.length(); ++i){AcDbGripData* pGrip = tempGripArr[i];DEL(tempGripArr[i]);tempGripArr[i] = NULL;}}}int n = CCustomBase::s_mapGripPtr.erase(pEnt);//如果删除了会返回1,否则返回0  return n;
}

CDiBanCsm.h

#pragma once
#include "CCustomBase.h"//底板
class CDiBanCsm :public CCustomBase
{public:ACRX_DECLARE_MEMBERS(CDiBanCsm);CDiBanCsm();CDiBanCsm(const AcGePoint3d& ptBase,double dLength,double dWidth);CDiBanCsm(const CDiBanCsm& obj);//拷贝构造函数~CDiBanCsm();#pragma region 重载函数virtual Acad::ErrorStatus getGripPoints(AcDbGripDataPtrArray& grips, const double curViewUnitSize, const int gripSize, const AcGeVector3d& curViewDir, const int bitflags) const;virtual Acad::ErrorStatus moveGripPointsAt(const AcDbVoidPtrArray& gripAppData,const AcGeVector3d& offset,const int bitflags);virtual Acad::ErrorStatus dwgInFields(AcDbDwgFiler* pFiler);//加载virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* pFiler) const;//保存virtual Acad::ErrorStatus transformBy(const AcGeMatrix3d& xform);virtual Acad::ErrorStatus explode(ZcDbVoidPtrArray& entitySet) const;virtual void gripStatus(const AcDb::GripStat status);virtual Adesk::Boolean worldDraw(AcGiWorldDraw* pWd);//绘制virtual Acad::ErrorStatus dxfInFields(AcDbDxfFiler* pFiler);virtual Acad::ErrorStatus dxfOutFields(AcDbDxfFiler* pFiler) const;virtual Acad::ErrorStatus getOsnapPoints(AcDb::OsnapMode osnapMode, Adesk::GsMarker gsSelectionMark, const AcGePoint3d& pickPoint, const AcGePoint3d& lastPoint,const AcGeMatrix3d& viewXform, AcGePoint3dArray& snapPoints, AcDbIntArray & geomIds) const;virtual Acad::ErrorStatus getGeomExtents(AcDbExtents& extents) const;virtual Acad::ErrorStatus getTransformedCopy(const AcGeMatrix3d& xform, AcDbEntity*& ent) const;virtual   Acad::ErrorStatus erase(Adesk::Boolean erasing = true);#pragma endregion 重载函数#pragma region 接口bool SetPosition(const AcGePoint3d& pt);//设置基点位置bool SetRotation(double dAngle);//设置旋转角度AcGeVector3d GetHoriDirection() const;//得到水平向量AcGeVector3d GetVertDirection() const;//得到垂直向量
#pragma endregion 接口#pragma region 辅助函数
protected://得到夹点坐标AcGePoint3d GetBaseGripPt() const;AcGePoint3d GetRightGripPt() const;AcGePoint3d GetTopGripPt() const;
#pragma endregion 辅助函数#pragma region 夹点
public://拉伸夹点static bool DrawStretchGrip(AcDbGripData *pThis, AcGiWorldDraw *pWd, const AcDbObjectId& entId, AcDbGripOperations::DrawType type, AcGePoint3d *cursor, double dGripSize);//转换夹点static bool DrawSwitchGrip(AcDbGripData *pThis, AcGiWorldDraw *pWd, const AcDbObjectId& entId, AcDbGripOperations::DrawType type, AcGePoint3d *cursor, double dGripSize);//枚举夹点static bool DrawEnumGrip(AcDbGripData *pThis, AcGiWorldDraw *pWd, const AcDbObjectId& entId, AcDbGripOperations::DrawType type, AcGePoint3d *cursor, double dGripSize);
#pragma endregion 夹点protected:AcDbLine m_lineHori1;AcDbLine m_lineHori2;AcDbLine m_lineVert1;AcDbLine m_lineVert2;AcGePoint3d m_ptBase; AcGePoint3d m_ptRight;  AcGePoint3d m_ptTop;double m_dLength;double m_dWidth;};

CDiBanCsm.cpp

#include "StdAfx.h"
#include "CDiBanCsm.h"ACRX_DXF_DEFINE_MEMBERS(CDiBanCsm, AcDbEntity, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,AcDbProxyEntity::kNoOperation, CDiBanCsm, ZwCad);CDiBanCsm::CDiBanCsm()
{m_arrEntPtr.append(&m_lineHori1);m_arrEntPtr.append(&m_lineHori2);m_arrEntPtr.append(&m_lineVert1);m_arrEntPtr.append(&m_lineVert2);m_vecGripName.clear();m_vecGripName.push_back(_T("BasePt"));m_vecGripName.push_back(_T("RightPt"));m_vecGripName.push_back(_T("TopPt"));
}CDiBanCsm::CDiBanCsm(const AcGePoint3d& ptBase, double dLength, double dWidth):m_ptBase(ptBase),m_dLength(dLength),m_dWidth(dWidth)
{//实体初始化m_ptRight = GetOffsetPt(m_ptBase, m_dLength, m_dWidth / 2);m_ptTop = GetOffsetPt(m_ptBase, m_dLength / 2, m_dWidth);m_lineHori1.setStartPoint(GetOffsetPt(m_ptBase,0, m_dWidth));m_lineHori1.setEndPoint(GetOffsetPt(m_ptBase, m_dLength, m_dWidth));m_lineHori2.setStartPoint(m_ptBase);m_lineHori2.setEndPoint(GetOffsetPt(m_ptBase, m_dLength, 0));m_lineVert1.setStartPoint(m_ptBase);m_lineVert1.setEndPoint(GetOffsetPt(m_ptBase, 0, m_dWidth));m_lineVert2.setStartPoint(GetOffsetPt(m_ptBase, m_dLength, 0));m_lineVert2.setEndPoint(GetOffsetPt(m_ptBase, m_dLength, m_dWidth));//添加实体指针,用于调用基类m_arrEntPtr.append(&m_lineHori1);m_arrEntPtr.append(&m_lineHori2);m_arrEntPtr.append(&m_lineVert1);m_arrEntPtr.append(&m_lineVert2);//添加夹点类型m_vecGripName.clear();m_vecGripName.push_back(_T("BasePt"));m_vecGripName.push_back(_T("RightPt"));m_vecGripName.push_back(_T("TopPt"));
}CDiBanCsm::CDiBanCsm(const CDiBanCsm& obj)
{m_lineHori1.setStartPoint(obj.m_lineHori1.startPoint());m_lineHori1.setEndPoint(obj.m_lineHori1.endPoint());m_lineHori2.setStartPoint(obj.m_lineHori2.startPoint());m_lineHori2.setEndPoint(obj.m_lineHori2.endPoint());m_lineVert1.setStartPoint(obj.m_lineVert1.startPoint());m_lineVert1.setEndPoint(obj.m_lineVert1.endPoint());m_lineVert2.setStartPoint(obj.m_lineVert2.startPoint());m_lineVert2.setEndPoint(obj.m_lineVert2.endPoint());m_ptBase = obj.m_ptBase;m_ptRight = obj.m_ptRight;m_ptTop = obj.m_ptTop;m_dLength = obj.m_dLength;m_dWidth = obj.m_dWidth;//添加实体指针,用于调用基类m_arrEntPtr.append(&m_lineHori1);m_arrEntPtr.append(&m_lineHori2);m_arrEntPtr.append(&m_lineVert1);m_arrEntPtr.append(&m_lineVert2);//添加夹点类型m_vecGripName.clear();m_vecGripName.push_back(_T("BasePt"));m_vecGripName.push_back(_T("RightPt"));m_vecGripName.push_back(_T("TopPt"));
}CDiBanCsm::~CDiBanCsm()
{}Adesk::Boolean CDiBanCsm::worldDraw(AcGiWorldDraw* pWd)
{assertReadEnabled();return CCustomBase::worldDraw(pWd);
}Acad::ErrorStatus CDiBanCsm::dwgInFields(AcDbDwgFiler* pFiler)
{//读取数据assertWriteEnabled();CCustomBase::dwgInFields(pFiler);pFiler->readPoint3d(&m_ptBase);pFiler->readPoint3d(&m_ptRight);pFiler->readPoint3d(&m_ptTop);return pFiler->filerStatus();
}Acad::ErrorStatus CDiBanCsm::dwgOutFields(AcDbDwgFiler* pFiler) const
{//存入数据assertReadEnabled();CCustomBase::dwgOutFields(pFiler);pFiler->writePoint3d(m_ptBase);pFiler->writePoint3d(m_ptRight);pFiler->writePoint3d(m_ptTop);return pFiler->filerStatus();
}Acad::ErrorStatus CDiBanCsm::dxfInFields(AcDbDxfFiler* pFiler)
{return Acad::eNotImplementedYet;
}Acad::ErrorStatus CDiBanCsm::dxfOutFields(AcDbDxfFiler* pFiler) const
{return Acad::eNotImplementedYet;
}Acad::ErrorStatus CDiBanCsm::getGripPoints(AcDbGripDataPtrArray& grips, const double curViewUnitSize, const int gripSize, const AcGeVector3d& curViewDir, const int bitflags) const
{assertReadEnabled();std::vector<CString>::const_iterator appIter = GetGripName();AcDbGripDataPtrArray tempGripArr;//BasePtAcDbGripData* pGripBase = new AcDbGripData();pGripBase->setAppData((void*)&(*appIter));pGripBase->setGripPoint(m_ptBase);grips.append(pGripBase);tempGripArr.append(pGripBase);appIter++;//RightPtAcDbGripData* pGripRight = new AcDbGripData();pGripRight->setAppData((void*)&(*appIter));pGripRight->setGripPoint(m_ptRight);pGripRight->setWorldDraw(DrawStretchGrip);grips.append(pGripRight);tempGripArr.append(pGripRight);appIter++;//TopPtAcDbGripData* pGripTop = new AcDbGripData();pGripTop->setAppData((void*)&(*appIter));pGripTop->setGripPoint(m_ptTop);pGripTop->setWorldDraw(DrawStretchGrip);grips.append(pGripTop);tempGripArr.append(pGripTop);appIter++;auto a = this;CCustomBase::s_mapGripPtr[this] = tempGripArr;return Acad::eOk;
}Acad::ErrorStatus CDiBanCsm::moveGripPointsAt(const AcDbVoidPtrArray& gripAppData,const AcGeVector3d& offset,
const int bitflags)
{assertWriteEnabled();CString* pStrTemp = NULL;for (int i = 0; i < gripAppData.length(); i++){pStrTemp = static_cast<CString*>(gripAppData[i]);if (*pStrTemp == _T("BasePt")){SetLinePoint(m_lineHori1, 3, offset);SetLinePoint(m_lineHori2, 3, offset);SetLinePoint(m_lineVert1, 3, offset);SetLinePoint(m_lineVert2, 3, offset);m_ptBase = GetBaseGripPt();m_ptRight = GetRightGripPt();m_ptTop = GetTopGripPt();}else if (*pStrTemp == _T("RightPt")){AcGePoint3d ptStart = m_lineHori2.startPoint();AcGePoint3d ptEnd = m_lineHori2.endPoint();AcGeVector3d vctHori = ptEnd - ptStart;AcGeVector3d vctOffset = GetProjectVector(m_ptBase, offset, vctHori);SetLinePoint(m_lineHori1,2,vctOffset);SetLinePoint(m_lineHori2, 2, vctOffset);SetLinePoint(m_lineVert2, 3, vctOffset);m_ptBase = GetBaseGripPt();m_ptRight = GetRightGripPt();m_ptTop = GetTopGripPt();}else if (*pStrTemp == _T("TopPt")){AcGePoint3d ptStart = m_lineVert1.startPoint();AcGePoint3d ptEnd = m_lineVert1.endPoint();AcGeVector3d vctHori = ptEnd - ptStart;AcGeVector3d vctOffset = GetProjectVector(m_ptBase, offset, vctHori);SetLinePoint(m_lineVert1, 2, vctOffset);SetLinePoint(m_lineVert2, 2, vctOffset);SetLinePoint(m_lineHori1, 3, vctOffset);m_ptBase = GetBaseGripPt();m_ptRight = GetRightGripPt();m_ptTop = GetTopGripPt();}}return Acad::eOk;
}Acad::ErrorStatus CDiBanCsm::getOsnapPoints(AcDb::OsnapMode osnapMode, Adesk::GsMarker gsSelectionMark, const AcGePoint3d& pickPoint, const AcGePoint3d& lastPoint, const AcGeMatrix3d& viewXform,AcGePoint3dArray& snapPoints, AcDbIntArray & geomIds) const
{assertReadEnabled();return CCustomBase::getOsnapPoints(osnapMode, gsSelectionMark, pickPoint, lastPoint, viewXform,snapPoints, geomIds);
}Acad::ErrorStatus CDiBanCsm::getGeomExtents(AcDbExtents& extents) const
{assertReadEnabled();return CCustomBase::getGeomExtents(extents);
}Acad::ErrorStatus CDiBanCsm::transformBy(const AcGeMatrix3d& xform)
{assertWriteEnabled();m_ptBase.transformBy(xform);m_ptRight.transformBy(xform);m_ptTop.transformBy(xform);return CCustomBase::transformBy(xform);
}Acad::ErrorStatus CDiBanCsm::getTransformedCopy(const AcGeMatrix3d& xform, AcDbEntity*& ent) const
{assertReadEnabled();return CCustomBase::getTransformedCopy(xform, ent);
}Acad::ErrorStatus CDiBanCsm::explode(ZcDbVoidPtrArray& entitySet) const
{assertReadEnabled();
//  entitySet.append(m_lineHori1.clone());
//  entitySet.append(m_lineHori2.clone());
//  entitySet.append(m_lineVert1.clone());
//  entitySet.append(m_lineVert2.clone());return Acad::eCannotExplodeEntity;
}Acad::ErrorStatus CDiBanCsm::erase(Adesk::Boolean erasing /*= true*/)
{assertWriteEnabled();return CCustomBase::erase(erasing);
}bool CDiBanCsm::SetPosition(const AcGePoint3d& pt)
{assertWriteEnabled();AcGeVector3d offset = pt - m_ptBase;SetLinePoint(m_lineHori1, 3, offset);SetLinePoint(m_lineHori2, 3, offset);SetLinePoint(m_lineVert1, 3, offset);SetLinePoint(m_lineVert2, 3, offset);m_ptBase = GetBaseGripPt();m_ptRight = GetRightGripPt();m_ptTop = GetTopGripPt();return true;
}bool CDiBanCsm::SetRotation(double dAngle)
{assertWriteEnabled();m_lineHori1.setStartPoint(GetOffsetPt(m_ptBase, 0, m_dWidth).rotateBy(dAngle,AcGeVector3d::kZAxis,m_ptBase));m_lineHori1.setEndPoint(GetOffsetPt(m_ptBase, m_dLength, m_dWidth).rotateBy(dAngle, AcGeVector3d::kZAxis, m_ptBase));m_lineHori2.setEndPoint(GetOffsetPt(m_ptBase, m_dLength, 0).rotateBy(dAngle, AcGeVector3d::kZAxis, m_ptBase));m_lineVert1.setEndPoint(GetOffsetPt(m_ptBase, 0, m_dWidth).rotateBy(dAngle, AcGeVector3d::kZAxis, m_ptBase));m_lineVert2.setStartPoint(GetOffsetPt(m_ptBase, m_dLength, 0).rotateBy(dAngle, AcGeVector3d::kZAxis, m_ptBase));m_lineVert2.setEndPoint(GetOffsetPt(m_ptBase, m_dLength, m_dWidth).rotateBy(dAngle, AcGeVector3d::kZAxis, m_ptBase));m_ptBase = GetBaseGripPt();m_ptRight = GetRightGripPt();m_ptTop = GetTopGripPt();return true;
}AcGeVector3d CDiBanCsm::GetHoriDirection() const
{AcGePoint3d ptStart = m_lineHori2.startPoint();AcGePoint3d ptEnd = m_lineHori2.endPoint();return ptEnd - ptStart;
}AcGeVector3d CDiBanCsm::GetVertDirection() const
{AcGePoint3d ptStart = m_lineVert1.startPoint();AcGePoint3d ptEnd = m_lineVert1.endPoint();return ptEnd - ptStart;
}void CDiBanCsm::gripStatus(const AcDb::GripStat status)
{AcDbEntity::gripStatus(status);switch (status){case AcDb::kGripsDone:CCustomBase::DeleteGrip(this);break;case AcDb::kGripsToBeDeleted:break;case AcDb::kDimDataToBeDeleted:break;}
}AcGePoint3d CDiBanCsm::GetBaseGripPt() const
{return m_lineHori2.startPoint();
}AcGePoint3d CDiBanCsm::GetRightGripPt() const
{AcGePoint3d ptStart = m_lineVert2.startPoint();AcGePoint3d ptEnd = m_lineVert2.endPoint();return AcGePoint3d((ptStart.x + ptEnd.x)/2,(ptStart.y + ptEnd.y)/2,(ptStart.z + ptEnd.z)/2);
}AcGePoint3d CDiBanCsm::GetTopGripPt() const
{AcGePoint3d ptStart = m_lineHori1.startPoint();AcGePoint3d ptEnd = m_lineHori1.endPoint();return AcGePoint3d((ptStart.x + ptEnd.x) / 2, (ptStart.y + ptEnd.y) / 2, (ptStart.z + ptEnd.z) / 2);
}bool CDiBanCsm::DrawStretchGrip(AcDbGripData *pThis, AcGiWorldDraw *pWd, const AcDbObjectId& entId, AcDbGripOperations::DrawType type, AcGePoint3d *cursor, double dGripSize)
{dGripSize *= CCustomBase::s_gripSize / 2;AcGePoint3d  pt = pThis->gripPoint();CString* pStr = (CString*)(pThis->appData());AcGeVector3d vec = AcGeVector3d::kXAxis;AcDbObjectPointer<CDiBanCsm> m_pDiBan(entId, AcDb::kForRead);if (m_pDiBan.openStatus() != Acad::eOk)return false;if (*pStr == _T("RightPt"))vec = m_pDiBan->GetHoriDirection().normal();else if (*pStr == _T("TopPt"))vec = m_pDiBan->GetVertDirection().normal();auto vecUp = AcGeVector3d::kZAxis.crossProduct(vec).normal();AcGePoint3d pts[3];pts[0] = pt + vec * dGripSize;pts[1] = pt - vec * dGripSize / 2 + vecUp * dGripSize * .7;pts[2] = pt - vec * dGripSize / 2 - vecUp * dGripSize * .7;pWd->subEntityTraits().setFillType(kAcGiFillAlways);pWd->geometry().polygon(3, pts);return true;
}bool CDiBanCsm::DrawSwitchGrip(AcDbGripData *pThis, AcGiWorldDraw *pWd, const AcDbObjectId& entId, AcDbGripOperations::DrawType type, AcGePoint3d *cursor, double dGripSize)
{dGripSize *= CCustomBase::s_gripSize / 2;AcGePoint3d  pt = pThis->gripPoint();AcGeVector3d vec = AcGeVector3d::kXAxis;auto vecUp = AcGeVector3d::kZAxis.crossProduct(vec).normal();AcGePoint3d ptsRec[4];ptsRec[0] = pt + vecUp * dGripSize;ptsRec[1] = pt + vecUp * dGripSize - vec * dGripSize;ptsRec[2] = pt - vecUp * dGripSize - vec * dGripSize;ptsRec[3] = pt - vecUp * dGripSize;AcGePoint3d ptsArr[3];ptsArr[0] = pt + vec * dGripSize * 2.4;ptsArr[1] = pt + vec * dGripSize + vecUp * dGripSize;ptsArr[2] = pt + vec * dGripSize - vecUp * dGripSize;pWd->subEntityTraits().setFillType(kAcGiFillAlways);pWd->geometry().polygon(4, ptsRec);pWd->geometry().polygon(3, ptsArr);return true;
}bool CDiBanCsm::DrawEnumGrip(AcDbGripData *pThis, AcGiWorldDraw *pWd, const AcDbObjectId& entId, AcDbGripOperations::DrawType type, AcGePoint3d *cursor, double dGripSize)
{dGripSize *= CCustomBase::s_gripSize / 2;AcGePoint3d  pt = pThis->gripPoint();// 中心圆pWd->subEntityTraits().setFillType(kAcGiFillAlways);pWd->geometry().circle(pt, dGripSize, AcGeVector3d::kZAxis);return true;
}

ObjectARX自定义实体相关推荐

  1. ObjectArx自定义实体入门(C++)及注意事项

    本文介绍了构造自定义实体的步骤.必须继承的函数和必须注意的事项 1.新建一个从AcDbEntity继承的类,如EntTest,必须添加的头文件: "stdarx.h"," ...

  2. 模具最小内腔尺寸标注,动态标注,确定即标注,ObjectARX自定义实体技术

    先看效果 模具内腔尺寸标注,主要用于寻找最小内腔,移动鼠标时,XY两个方向的标注均会自动更新位置和尺寸值,点击确定即可标注. 程序使用ObjectARX和Jig技术进行编写,支持AutoCAD.中望. ...

  3. ObjectArx创建自定义实体

    ObjectArx创建自定义实体 一.目的 在ObjectArx中已经有了许多实体,如AcDbLine,AcDbCircle,AcDbArc等,但在用户使用Cad时,会有一些对他们来讲常用的" ...

  4. ObjectARX C++自定义实体

    ObjectARX C++自定义实体 实现流程 首先创建一个继承自AcDbEntity的自定义实体类,重写几个虚函数方法: .从AcDbEntity类中重载几个必须的虚函数: virtual Ades ...

  5. ObjectARX简单自定义实体的实现

    目录 1. ObjectARX向导(Wizard)的安装 2. 创建自定义实体工程CustomStair 3. 添加实体类 3.1 利用向导添加自定义类 3.2 "初始化"自定义类 ...

  6. ObjectARX第一课:创建自定义实体

    源地址:https://blog.csdn.net/u012158162/article/details/67644392 一.目的 在ObjectArx中已经有了许多实体,如AcDbLine,AcD ...

  7. 专题---自定义实体类

    目录 一.概述 二.项目初始化 2.1 创建空解决方案 2.2 DBX操作 2.2.1 创建DBX 2.2.2 调试DBX 2.2.3 创建实体类 2.2.4 调试实体类 2.3 ARX操作 2.3. ...

  8. 掌握 ASP.NET 之路:自定义实体类简介

    发布日期 : 5/24/2005| 更新日期 : 5/24/2005 Karl Seguin Microsoft Corporation 摘要:有些情况下,非类型化的 DataSet 可能并非数据操作 ...

  9. 掌握 ASP.NET 之路:自定义实体类简介 来源 :msdn

    ADODB.RecordSet 和常常被遗忘的 MoveNext 的时代已经过去,取而代之的是 Microsoft ADO.NET 强大而又灵活的功能.我们的新武器就是 System.Data 名称空 ...

最新文章

  1. python open encoding为无效的参数_TypeError:“encoding”是无效的关键字参数ex23.py
  2. ubuntu10.10编译qtopia-2.2.0 问题总结及分析
  3. 小白使用ansible
  4. 教你用命令行扩展VHD的大小
  5. ThinkPHP3.2.3目录结构
  6. OpenCV--SVM多分类问题
  7. 23个适合logo设计的常用英文字体
  8. UniBeast:在任何支持基于英特尔处理器的PC上安装OS X优胜美地
  9. echo和narcissus寓意_【故事】三毛的英文名Echo,有什么含义?
  10. 清华2018计算机研究所录取结果,2018年清华北大自主招生录取名单公布!
  11. bus error的解决方法
  12. 陕西计算机中考考试,2018年陕西省中考考试时间及科目安排公布
  13. wp-bugku-秋名山老司机
  14. 李宏毅机器学习之RNN
  15. 特殊符号,emoji表情,四字节去除问题
  16. 撩魅登录时显示服务器错误是什么意思,暧昧期女生撩男生的套路 暧昧的时候要注意什么...
  17. Surface 3 重做系统官方步骤
  18. java用hutool.excelUtil实现excel创建模板和下载模板
  19. SSM的小说上传下载网站含前后台-JAVA【数据库设计、源码、开题报告】
  20. 团战可以输、提莫必须死

热门文章

  1. 一篇解释清楚Cookie是什么?
  2. 4. PCIe 接口时序
  3. 啥是单点登录及单点登录原理
  4. 精心整理史上最全的数据结构flash演示动画,共5个版本,祝大家考研成功!
  5. LOX-8 Grease Paste tufoil fluoramics
  6. 工业软件CAD、CAE、CAM介绍
  7. 力学专业做cae需要学c语言吗,CAE工程师是需要掌握力学知识到何种程度?
  8. protege 简介
  9. make: *** No targets specified and no makefile found. Stop.错误解决办法
  10. ContextMenu(上下文菜单)的用法