1、创建空白解决方案。
2、添加自定义实体工程(自定义三角行实体)
3、添加类,选择Custom Object Wizard,定义实体名,选择继承AcDbEntity实体基类
4、设置捕捉模式、数据读写格式规则
5、工程目录
6、编写实体在DWG、DXF文件读写
头文件中添加成员变量存储三角形顶点,添加构造函数
源文件中实现构造函数,
源文件中dwgOutFields、dwgInFields、dxfOutFields、dxfInFields函数进行变量存储和读取
源文件中subWorldDraw添加图形绘制
ArxCusEntity.h头文件
// (C) Copyright 2002-2007 by Autodesk, Inc. // // Permission to use, copy, modify, and distribute this software in // object code form for any purpose and without fee is hereby granted, // provided that the above copyright notice appears in all copies and // that both that copyright notice and the limited warranty and // restricted rights notice below appear in all supporting // documentation. // // AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. // AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. // DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE // UNINTERRUPTED OR ERROR FREE. // // Use, duplication, or disclosure by the U.S. Government is subject to // restrictions set forth in FAR 52.227-19 (Commercial Computer // Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) // (Rights in Technical Data and Computer Software), as applicable. // //----------------------------------------------------------------------------- //----- ArxCusEntity.h : Declaration of the ArxCusEntity //----------------------------------------------------------------------------- #pragma once #ifdef DEMO_CUSTOMENTITY_MODULE #define DLLIMPEXP __declspec(dllexport) #else //----- Note: we don't use __declspec(dllimport) here, because of the //----- "local vtable" problem with msvc. If you use __declspec(dllimport), //----- then, when a client dll does a new on the class, the object's //----- vtable pointer points to a vtable allocated in that client //----- dll. If the client dll then passes the object to another dll, //----- and the client dll is then unloaded, the vtable becomes invalid //----- and any virtual calls on the object will access invalid memory. //----- //----- By not using __declspec(dllimport), we guarantee that the //----- vtable is allocated in the server dll during the ctor and the //----- client dll does not overwrite the vtable pointer after calling //----- the ctor. And, since we expect the server dll to remain in //----- memory indefinitely, there is no problem with vtables unexpectedly //----- going away. #define DLLIMPEXP #endif //----------------------------------------------------------------------------- #include "dbmain.h" //----------------------------------------------------------------------------- class DLLIMPEXP ArxCusEntity : public AcDbEntity { public: ACRX_DECLARE_MEMBERS(ArxCusEntity) ; protected: static Adesk::UInt32 kCurrentVersionNumber ; public: ArxCusEntity () ; //重载构造函数 ArxCusEntity (AcGePoint3d P1,AcGePoint3d P2,AcGePoint3d P3) ; virtual ~ArxCusEntity () ; //----- AcDbObject protocols //- Dwg Filing protocol virtual Acad::ErrorStatus dwgOutFields (AcDbDwgFiler *pFiler) const ; virtual Acad::ErrorStatus dwgInFields (AcDbDwgFiler *pFiler) ; //- Dxf Filing protocol virtual Acad::ErrorStatus dxfOutFields (AcDbDxfFiler *pFiler) const ; virtual Acad::ErrorStatus dxfInFields (AcDbDxfFiler *pFiler) ; //----- AcDbEntity protocols //- Graphics protocol protected: virtual Adesk::Boolean subWorldDraw (AcGiWorldDraw *mode) ; virtual Adesk::UInt32 subSetAttributes (AcGiDrawableTraits *traits) ; //- Osnap points protocol public: virtual Acad::ErrorStatus subGetOsnapPoints ( AcDb::OsnapMode osnapMode, int gsSelectionMark, const AcGePoint3d &pickPoint, const AcGePoint3d &lastPoint, const AcGeMatrix3d &viewXform, AcGePoint3dArray &snapPoints, AcDbIntArray &geomIds) const ; virtual Acad::ErrorStatus subGetOsnapPoints ( AcDb::OsnapMode osnapMode, int gsSelectionMark, const AcGePoint3d &pickPoint, const AcGePoint3d &lastPoint, const AcGeMatrix3d &viewXform, AcGePoint3dArray &snapPoints, AcDbIntArray &geomIds, const AcGeMatrix3d &insertionMat) const ; //- Grip points protocol virtual Acad::ErrorStatus subGetGripPoints (AcGePoint3dArray &gripPoints, AcDbIntArray &osnapModes, AcDbIntArray &geomIds) const ; virtual Acad::ErrorStatus subMoveGripPointsAt (const AcDbIntArray &indices, const AcGeVector3d &offset) ; virtual Acad::ErrorStatus subGetGripPoints ( AcDbGripDataPtrArray &grips, const double curViewUnitSize, const int gripSize, const AcGeVector3d &curViewDir, const int bitflags) const ; virtual Acad::ErrorStatus subMoveGripPointsAt (const AcDbVoidPtrArray &gripAppData, const AcGeVector3d &offset, const int bitflags) ; private: //定义数组,存储三角形三个顶点 AcGePoint3d m_verts[3]; } ; #ifdef DEMO_CUSTOMENTITY_MODULE ACDB_REGISTER_OBJECT_ENTRY_AUTO(ArxCusEntity) #endif
ArxCusEntity.cpp
// (C) Copyright 2002-2007 by Autodesk, Inc. // // Permission to use, copy, modify, and distribute this software in // object code form for any purpose and without fee is hereby granted, // provided that the above copyright notice appears in all copies and // that both that copyright notice and the limited warranty and // restricted rights notice below appear in all supporting // documentation. // // AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. // AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. // DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE // UNINTERRUPTED OR ERROR FREE. // // Use, duplication, or disclosure by the U.S. Government is subject to // restrictions set forth in FAR 52.227-19 (Commercial Computer // Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) // (Rights in Technical Data and Computer Software), as applicable. // //----------------------------------------------------------------------------- //----- ArxCusEntity.cpp : Implementation of ArxCusEntity //----------------------------------------------------------------------------- #include "StdAfx.h" #include "ArxCusEntity.h" //----------------------------------------------------------------------------- Adesk::UInt32 ArxCusEntity::kCurrentVersionNumber =1 ; //----------------------------------------------------------------------------- ACRX_DXF_DEFINE_MEMBERS ( ArxCusEntity, AcDbEntity, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, AcDbProxyEntity::kNoOperation, ARXCUSENTITY, ARXDEMO_CUSTOMENTITYAPP |Product Desc: A description for your object |Company: Your company name |WEB Address: Your company WEB site address ) //----------------------------------------------------------------------------- ArxCusEntity::ArxCusEntity () : AcDbEntity () { } ArxCusEntity::ArxCusEntity( AcGePoint3d P1,AcGePoint3d P2,AcGePoint3d P3 ) { m_verts[0] = P1; m_verts[1] = P2; m_verts[2] = P3; } ArxCusEntity::~ArxCusEntity () { } //----------------------------------------------------------------------------- //----- AcDbObject protocols //- Dwg Filing protocol Acad::ErrorStatus ArxCusEntity::dwgOutFields (AcDbDwgFiler *pFiler) const { assertReadEnabled () ; //----- Save parent class information first. Acad::ErrorStatus es =AcDbEntity::dwgOutFields (pFiler) ; if ( es != Acad::eOk ) return (es) ; //----- Object version number needs to be saved first if ( (es =pFiler->writeUInt32 (ArxCusEntity::kCurrentVersionNumber)) != Acad::eOk ) return (es) ; //----- Output params //.....写入成员变量数据 for(int i=0; i< 3;i++){ pFiler->writeItem(m_verts[i]); } return (pFiler->filerStatus ()) ; } Acad::ErrorStatus ArxCusEntity::dwgInFields (AcDbDwgFiler *pFiler) { assertWriteEnabled () ; //----- Read parent class information first. Acad::ErrorStatus es =AcDbEntity::dwgInFields (pFiler) ; if ( es != Acad::eOk ) return (es) ; //----- Object version number needs to be read first Adesk::UInt32 version =0 ; if ( (es =pFiler->readUInt32 (&version)) != Acad::eOk ) return (es) ; if ( version > ArxCusEntity::kCurrentVersionNumber ) return (Acad::eMakeMeProxy) ; //- Uncomment the 2 following lines if your current object implementation cannot //- support previous version of that object. //if ( version < ArxCusEntity::kCurrentVersionNumber ) // return (Acad::eMakeMeProxy) ; //----- Read params //.....读取成员变量数值 for (int i=0; i<3; i++) { pFiler->readItem(&m_verts[i]); } return (pFiler->filerStatus ()) ; } //- Dxf Filing protocol Acad::ErrorStatus ArxCusEntity::dxfOutFields (AcDbDxfFiler *pFiler) const { assertReadEnabled () ; //----- Save parent class information first. Acad::ErrorStatus es =AcDbEntity::dxfOutFields (pFiler) ; if ( es != Acad::eOk ) return (es) ; es =pFiler->writeItem (AcDb::kDxfSubclass, _RXST("ArxCusEntity")) ; if ( es != Acad::eOk ) return (es) ; //----- Object version number needs to be saved first if ( (es =pFiler->writeUInt32 (kDxfInt32, ArxCusEntity::kCurrentVersionNumber)) != Acad::eOk ) return (es) ; //----- Output params return (pFiler->filerStatus ()) ; } Acad::ErrorStatus ArxCusEntity::dxfInFields (AcDbDxfFiler *pFiler) { assertWriteEnabled () ; //----- Read parent class information first. Acad::ErrorStatus es =AcDbEntity::dxfInFields (pFiler) ; if ( es != Acad::eOk || !pFiler->atSubclassData (_RXST("ArxCusEntity")) ) return (pFiler->filerStatus ()) ; //----- Object version number needs to be read first struct resbuf rb ; pFiler->readItem (&rb) ; if ( rb.restype != AcDb::kDxfInt32 ) { pFiler->pushBackItem () ; pFiler->setError (Acad::eInvalidDxfCode, _RXST("\nError: expected group code %d (version #)"), AcDb::kDxfInt32) ; return (pFiler->filerStatus ()) ; } Adesk::UInt32 version =(Adesk::UInt32)rb.resval.rlong ; if ( version > ArxCusEntity::kCurrentVersionNumber ) return (Acad::eMakeMeProxy) ; //- Uncomment the 2 following lines if your current object implementation cannot //- support previous version of that object. //if ( version < ArxCusEntity::kCurrentVersionNumber ) // return (Acad::eMakeMeProxy) ; //----- Read params in non order dependant manner while ( es == Acad::eOk && (es =pFiler->readResBuf (&rb)) == Acad::eOk ) { switch ( rb.restype ) { //----- Read params by looking at their DXF code (example below) //case AcDb::kDxfXCoord: // if ( version == 1 ) // cen3d =asPnt3d (rb.resval.rpoint) ; // else // cen2d =asPnt2d (rb.resval.rpoint) ; // break ; default: //----- An unrecognized group. Push it back so that the subclass can read it again. pFiler->pushBackItem () ; es =Acad::eEndOfFile ; break ; } } //----- At this point the es variable must contain eEndOfFile //----- - either from readResBuf() or from pushback. If not, //----- it indicates that an error happened and we should //----- return immediately. if ( es != Acad::eEndOfFile ) return (Acad::eInvalidResBuf) ; return (pFiler->filerStatus ()) ; } //----------------------------------------------------------------------------- //----- AcDbEntity protocols Adesk::Boolean ArxCusEntity::subWorldDraw (AcGiWorldDraw *mode) { assertReadEnabled () ; //绘制图形 for (int i =0; i < 3 ;i++) { int nextIndex = i +1; if(i ==2) { nextIndex = 0; } AcGePoint3d points[2]; points[0] = m_verts[i]; points[1] = m_verts[nextIndex]; mode->geometry().polyline(2,points); } return (AcDbEntity::subWorldDraw (mode)) ; } Adesk::UInt32 ArxCusEntity::subSetAttributes (AcGiDrawableTraits *traits) { assertReadEnabled () ; return (AcDbEntity::subSetAttributes (traits)) ; } //- Osnap points protocol Acad::ErrorStatus ArxCusEntity::subGetOsnapPoints ( AcDb::OsnapMode osnapMode, int gsSelectionMark, const AcGePoint3d &pickPoint, const AcGePoint3d &lastPoint, const AcGeMatrix3d &viewXform, AcGePoint3dArray &snapPoints, AcDbIntArray &geomIds) const { assertReadEnabled () ; return (AcDbEntity::subGetOsnapPoints (osnapMode, gsSelectionMark, pickPoint, lastPoint, viewXform, snapPoints, geomIds)) ; } Acad::ErrorStatus ArxCusEntity::subGetOsnapPoints ( AcDb::OsnapMode osnapMode, int gsSelectionMark, const AcGePoint3d &pickPoint, const AcGePoint3d &lastPoint, const AcGeMatrix3d &viewXform, AcGePoint3dArray &snapPoints, AcDbIntArray &geomIds, const AcGeMatrix3d &insertionMat) const { assertReadEnabled () ; return (AcDbEntity::subGetOsnapPoints (osnapMode, gsSelectionMark, pickPoint, lastPoint, viewXform, snapPoints, geomIds, insertionMat)) ; } //- Grip points protocol Acad::ErrorStatus ArxCusEntity::subGetGripPoints ( AcGePoint3dArray &gripPoints, AcDbIntArray &osnapModes, AcDbIntArray &geomIds ) const { assertReadEnabled () ; //----- This method is never called unless you return eNotImplemented //----- from the new getGripPoints() method below (which is the default implementation) return (AcDbEntity::subGetGripPoints (gripPoints, osnapModes, geomIds)) ; } Acad::ErrorStatus ArxCusEntity::subMoveGripPointsAt (const AcDbIntArray &indices, const AcGeVector3d &offset) { assertWriteEnabled () ; //----- This method is never called unless you return eNotImplemented //----- from the new moveGripPointsAt() method below (which is the default implementation) return (AcDbEntity::subMoveGripPointsAt (indices, offset)) ; } Acad::ErrorStatus ArxCusEntity::subGetGripPoints ( AcDbGripDataPtrArray &grips, const double curViewUnitSize, const int gripSize, const AcGeVector3d &curViewDir, const int bitflags ) const { assertReadEnabled () ; //----- If you return eNotImplemented here, that will force AutoCAD to call //----- the older getGripPoints() implementation. The call below may return //----- eNotImplemented depending of your base class. return (AcDbEntity::subGetGripPoints (grips, curViewUnitSize, gripSize, curViewDir, bitflags)) ; } Acad::ErrorStatus ArxCusEntity::subMoveGripPointsAt ( const AcDbVoidPtrArray &gripAppData, const AcGeVector3d &offset, const int bitflags ) { assertWriteEnabled () ; //----- If you return eNotImplemented here, that will force AutoCAD to call //----- the older getGripPoints() implementation. The call below may return //----- eNotImplemented depending of your base class. return (AcDbEntity::subMoveGripPointsAt (gripAppData, offset, bitflags)) ; }
1、在解决方案下创建Arx测试项目,引用自定义实体
设置测试项目为当前启动项目,鼠标右键引用自定义实体工程
2、在测试项目中添加用户命令,添加自定义实体头文件
// (C) Copyright 2002-2007 by Autodesk, Inc. // // Permission to use, copy, modify, and distribute this software in // object code form for any purpose and without fee is hereby granted, // provided that the above copyright notice appears in all copies and // that both that copyright notice and the limited warranty and // restricted rights notice below appear in all supporting // documentation. // // AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. // AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. // DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE // UNINTERRUPTED OR ERROR FREE. // // Use, duplication, or disclosure by the U.S. Government is subject to // restrictions set forth in FAR 52.227-19 (Commercial Computer // Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) // (Rights in Technical Data and Computer Software), as applicable. // //----------------------------------------------------------------------------- //----- acrxEntryPoint.cpp //----------------------------------------------------------------------------- #include "StdAfx.h" #include "resource.h" #include "../Demo_CustomEntity/ArxCusEntity.h" //----------------------------------------------------------------------------- #define szRDS _RXST("Arx") //----------------------------------------------------------------------------- //----- ObjectARX EntryPoint class CDemo_TSTCustomEntityApp : public AcRxArxApp { public: CDemo_TSTCustomEntityApp () : AcRxArxApp () {} virtual AcRx::AppRetCode On_kInitAppMsg (void *pkt) { // TODO: Load dependencies here // You *must* call On_kInitAppMsg here AcRx::AppRetCode retCode =AcRxArxApp::On_kInitAppMsg (pkt) ; // TODO: Add your initialization code here return (retCode) ; } virtual AcRx::AppRetCode On_kUnloadAppMsg (void *pkt) { // TODO: Add your code here // You *must* call On_kUnloadAppMsg here AcRx::AppRetCode retCode =AcRxArxApp::On_kUnloadAppMsg (pkt) ; // TODO: Unload dependencies here return (retCode) ; } virtual void RegisterServerComponents () { } // - ArxDemo_TSTCustomEntity._MyCommand1 command (do not rename) static void ArxDemo_TSTCustomEntity_MyCommand1(void) { // Add your code for command ArxDemo_TSTCustomEntity._MyCommand1 here //定义自定义实体 ArxCusEntity *pArxArxCusEntity = new ArxCusEntity(AcGePoint3d(0,0,0),AcGePoint3d(100,0,0),AcGePoint3d(100,100,30)); AcDbBlockTable *pBlockTable =NULL; //打开块表 acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable,AcDb::kForRead); AcDbBlockTableRecord *pBockTableRecord = NULL; //打开模型空间 pBlockTable->getAt(ACDB_MODEL_SPACE,pBockTableRecord,AcDb::kForWrite); AcDbObjectId lineId; //添加实体到模型空间 pBockTableRecord->appendAcDbEntity(lineId,pArxArxCusEntity); pBlockTable->close(); pBockTableRecord->close(); pArxArxCusEntity->close(); } } ; //----------------------------------------------------------------------------- IMPLEMENT_ARX_ENTRYPOINT(CDemo_TSTCustomEntityApp) ACED_ARXCOMMAND_ENTRY_AUTO(CDemo_TSTCustomEntityApp, ArxDemo_TSTCustomEntity, _MyCommand1, MyCommand1, ACRX_CMD_TRANSPARENT, NULL)