[ObjectARX]-在图形数据库之间传递数据 Wblock

(1)使用ObjectARX向导创建一个新工程,名称为Wblock.

添加普通类CBlockUtil,并在类中添加函数CopyBlockDefOtherDwg,用于将其他Dwg文件 中的块定义赋值到当前图形数据库。

实现代码:

AcDbObjectId CBlockUtil::CopyBlockDefFromOtherDwg(const TCHAR* fileName,
	const TCHAR* blkDefName)
{
	AcDbObjectId blockRefId = AcDbObjectId::kNull;
	                        //AcDbObjectId :: kNull表示当前DWG中不存在对象(图层)

	//使用_SH_DENYNO参数打开图形(只读打开),允许其他用户读写文件
	AcDbDatabase* pSourceDwg = new AcDbDatabase(false);
	Acad::ErrorStatus es = pSourceDwg->readDwgFile(fileName,
		static_cast<AcDbDatabase::OpenMode>(_SH_DENYNO));
	if (es != Acad::eOk)
	{
		delete pSourceDwg;
		pSourceDwg = NULL;

		acutPrintf(TEXT("\n读入dwg图形错误,图形名称:%s"), fileName);
		return blockRefId;
	}

	//打开外部图形数据库的块表,寻找给定名称的块表记录
	AcDbBlockTable* pBlkTable = NULL;
	es = pSourceDwg->getBlockTable(pBlkTable, AcDb::kForRead);
	                 //以只读模式打开数据库的块表,pBlkTable获得块表地址
	assert(es == Acad::eOk);
	bool bRet = false;

	if (pBlkTable->has(blkDefName))  //不存在指定的图块
	{
		AcDbObjectId destBlkDefId; //指定图块的块表记录Id
		es = pBlkTable->getAt(blkDefName, destBlkDefId);

		//把指定的图块输出到一个临时的图形数据库
		AcDbDatabase *pTempDb = NULL;  //注意:这里千万不能new
		es = pSourceDwg->wblock(pTempDb, destBlkDefId);//创建一个新的数据库对象,pTempDb指向它
		assert(es == Acad::eOk);

		//把临时图形数据库作为插入块插入到当前dwg
		AcDbDatabase* pCurDb = acdbHostApplicationServices()->workingDatabase();
		es = pCurDb->insert(blockRefId, blkDefName, pTempDb);//由pDb指向的数据库中的所有
            //模型空间实体都被复制到新的块表记录中,新的块表记录名称为blkDefName,Id为blockRefId
		assert(es == Acad::eOk);
		delete pTempDb;
		pTempDb = NULL;
	}
	else
	{
		acutPrintf(TEXT("\n给定的DWG文件中,不存在指定名称的块表记录."));
	}
	pBlkTable->close();

	delete pSourceDwg;
	pSourceDwg = NULL;

	return blockRefId;
}

(2)在CBlockUtil类中添加函数InsertDwgBlockDef,用于将指定的整个DWG文件作为图块加入到当前图形文件中作为块定义。

实现代码:

InsertDwgBlockDef函数的声明:

	// 将DWG文件作为块定义加入到指定的图形数据库
	// bOverwriteIfExist: 如果指定的图形数据库中已经定义了同名的块,是否覆盖原有的定义
	static AcDbObjectId InsertDwgBlockDef(const TCHAR* dwgFileName, 
              const TCHAR* blkName, bool bOverwriteIfExist, 
		      AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase());

InsertDwgBlockDef函数的实现:

   AcDbObjectId CBlockUtil::InsertDwgBlockDef(const TCHAR* dwgFileName,
	const TCHAR* blkName, bool bOverwriteIfExist, AcDbDatabase *pDb)
{
	//是否包含指定名称的块定义
	AcDbObjectId blkDefId = GetBlkDefId(blkName, pDb);
	if (blkDefId.isNull() || bOverwriteIfExist)
	{
		if (_taccess(dwgFileName, 0) != -1)//如果指定的文件不存在,返回-1
		{
			AcDbDatabase *pBlkDb = new AcDbDatabase(false);
			Acad::ErrorStatus es = pBlkDb->readDwgFile(dwgFileName, 
				              static_cast<AcDbDatabase::OpenMode>(_SH_DENYNO));
			if (es == Acad::eOk)
			{
				es = pDb->insert(blkDefId, blkName, pBlkDb);//在执行此insert函数的数据库中
				              //创建新的块表记录;由pBlkDb指向的数据库中的所有模型空间实体都
				              //被复制到新的块表记录中,名称为blkName,Id为blkDefId
				if (es != Acad::eOk)
				{
					CString strMsg;
					strMsg.Format(TEXT("CBlockUtil::InsertDwgBlockDef函数,insert失败:%d."),
						(int)es);
					AfxMessageBox(strMsg);
				}
			}
			else
			{
				CString strMsg;
				strMsg.Format(TEXT("CBlockUtil::InsertDwgBlockDef函数,readDwg File失败:%d."), 
					(int)es);
				AfxMessageBox(strMsg);
			}
			delete pBlkDb;
		}
		else
		{
			AfxMessageBox(TEXT("CBlockUtil::InsertDwgBlockDef函数,未找到指定的图块文件."));
		}
	}
	return blkDefId;
}

其中,

GetBlkDefId函数的声明:

	// 获得指定名称的块定义
	static AcDbObjectId GetBlkDefId(const TCHAR* blkDefName,
 AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase());

GetBlkDefId函数的实现:

// 获得指定名称的块定义
AcDbObjectId CBlockUtil::GetBlkDefId(const TCHAR* blkDefName, AcDbDatabase *pDb)
{
	AcDbBlockTable* pBlockTable = NULL;
	Acad::ErrorStatus es = pDb->getBlockTable(pBlockTable, AcDb::kForRead);
	AcDbObjectId blkDefId;
	es = pBlockTable->getAt(blkDefName, blkDefId);
	pBlockTable->close();

	if (es == Acad::eOk)
	{
		return blkDefId;
	}
	else
	{
		return AcDbObjectId::kNull;
	}
}

 (3)注册函命令InsertBlkRefFromOtherDwg,将外部图形文件中的块定义复制到当前图形文件,然后在图形窗口中插入这个块定义的块参照。

注册函数InsertBlkRefFromOtherDwg的实现代码:

static void AAAMyGroupInsertBlkRefFromOtherDwg() {
		CString fileName = TEXT("C:\\'包含图块.dwg");
		if (_taccess(fileName, 0) != -1)
		{
			AcDbObjectId blkDefId = CBlockUtil::CopyBlockDefFromOtherDwg(fileName, 
				TEXT("测试图块"));
			if (blkDefId.isValid())
			{
				CBlockUtil::InsertBlockRef(blkDefId, AcGePoint3d(100, 100, 0), 1, 0);
			}
		}
		else
		{
			acutPrintf(TEXT("\n指定的图形文件不存在"));
		}

	}

其中,

InsertBlockRef函数的声明:

	// 插入块参照
	static AcDbObjectId InsertBlockRef(AcDbObjectId blkDefId, const AcGePoint3d &insertPoint,
 double scale = 1, double rotation = 0);

InsertBlockRef函数的实现:

// 插入块参照
AcDbObjectId CBlockUtil::InsertBlockRef(AcDbObjectId blkDefId, const AcGePoint3d &insertPoint, double scale,
	double rotation)
{
	// 设置图块的插入点、旋转角度、比例等等
	AcDbBlockReference *pBlkRef = new AcDbBlockReference(insertPoint, blkDefId);
	pBlkRef->setRotation(rotation);
	SetScaleFactor(pBlkRef, scale);

	// 把新建的图块参照实体加入到新建的块表记录中,并取得插入图块的实体Id,用于返回值
	return CDwgDatabaseUtil::PostToModelSpace(pBlkRef);
}

② 

SetScaleFactor函数的声明: 


	// 设置块参照的缩放比例
	static void SetScaleFactor(AcDbBlockReference *pBlkRef, double scale);

SetScaleFactor函数的实现:  

// 修改块参照的插入比例
void CBlockUtil::SetScaleFactor( AcDbBlockReference *pBlkRef, double scale )
{
	assert (pBlkRef);
	
	AcGeScale3d geScale(scale, scale, scale);
	pBlkRef->setScaleFactors(geScale);
}

③ 

PostToModelSpace函数的声明:

	// 将实体添加到模型空间
	static AcDbObjectId PostToModelSpace(AcDbEntity *pEnt, 
     AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase());

PostToModelSpace函数的声明: 


AcDbObjectId CDwgDatabaseUtil::PostToModelSpace(AcDbEntity *pEnt, AcDbDatabase *pDb)
{
	// 检查输入参数的有效性
	assert(pEnt);		// 等效于assert (pEnt != NULL);

						// 获得当前图形数据库的块表
	AcDbBlockTable *pBlkTbl = NULL;
	pDb->getBlockTable(pBlkTbl, AcDb::kForRead);

	// 获得模型空间对应的块表记录
	AcDbBlockTableRecord *pBlkTblRcd = NULL;
	pBlkTbl->getAt(ACDB_MODEL_SPACE, pBlkTblRcd, AcDb::kForWrite);
	pBlkTbl->close();

	// 将实体添加到模型空间的块表记录
	AcDbObjectId entId;
	Acad::ErrorStatus es = pBlkTblRcd->appendAcDbEntity(entId, pEnt);
	if (es != Acad::eOk)
	{
		pBlkTblRcd->close();
		delete pEnt;	// 添加失败时,要delete
		pEnt = NULL;

		return AcDbObjectId::kNull;
	}

	// 关闭模型空间块表记录和实体
	pBlkTblRcd->close();
	pEnt->close();

	return entId;
}

(4)注册命令InsertDwgBlockRef,将某个DWG文件作为图块插入到当前的模型空间。

实现代码为:

注册函数InsertDwgBlockRef 的实现:

	static void AAAMyGroupInsertDwgBlockRef() {
		CString fileName = TEXT("C:\\作为图块的文件.dwg");
		if (_taccess(fileName, 0) != -1)
		{
			AcDbObjectId blkDefId = CBlockUtil::InsertDwgBlockDef(fileName,
				TEXT("外部DWG图块"), true);
			if (blkDefId.isValid())
			{
				CBlockUtil::InsertBlockRef(blkDefId, AcGePoint3d(200, 100, 0), 1, 0);
			}
		}
		else
		{
			acutPrintf(TEXT("\n指定的图形文件不存在."));
		}

	}

思路总结: 

 

完整的项目源代码:

     https://pan.baidu.com/s/1nIM7NcpE__IZ8n1GTga6AA

<未完待续>

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
从acdbmgd.dll导出的内容,方便参考,格式如下: 类:Autodesk.AutoCAD.DatabaseServices.TextStyleTableRecord:Autodesk.AutoCAD.DatabaseServices.SymbolTableRecord New() 方法: {dtor}() {dtor}() {dtor}() {dtor}() ApplyPaperOrientationTransform(Viewport) ApplyPartialUndo(DwgFiler,RXClass) Audit(AuditInfo) Cancel() Close() CloseAndPage(Boolean) CopyFrom(RXObject) CreateExtensionDictionary() DisableUndoRecording(Boolean) Dispose() DowngradeOpen() DowngradeToNotify(Boolean) DwgIn(DwgFiler) DwgOut(DwgFiler) DxfIn(DxfFiler) DxfOut(DxfFiler) Erase() Erase(Boolean) HandOverTo(DBObject,Boolean,Boolean) ReleaseExtensionDictionary() RemoveField(ObjectId) ResetScaleDependentProperties() SetObjectIdsInFlux() SetPaperOrientation(Boolean) SwapIdWith(ObjectId,Boolean,Boolean) SwapReferences(IdMapping) UpgradeOpen() ViewportDraw(ViewportDraw) XDataTransformBy(Matrix3d) 函数: Clone() AS System.Object CompareTo(Object) AS System.Int32 CreateObjRef(Type) AS System.Runtime.Remoting.ObjRef DecomposeForSave(DwgVersion) AS Autodesk.AutoCAD.DatabaseServices.DecomposeForSaveReplacementRecord DeepClone(DBObject,IdMapping,Boolean) AS Autodesk.AutoCAD.DatabaseServices.DBObject Equals(Object) AS System.Boolean GetHashCode() AS System.Int32 GetLifetimeService() AS System.Object GetObjectSaveVersion(DwgFiler) AS Autodesk.AutoCAD.DatabaseServices.FullDwgVersion GetObjectSaveVersion(DxfFiler) AS Autodesk.AutoCAD.DatabaseServices.FullDwgVersion GetPersistentReactorIds() AS Autodesk.AutoCAD.DatabaseServices.ObjectIdCollection GetReactors() AS System.Collections.Generic.List`1[[Autodesk.AutoCAD.Runtime.RXObject, acdbmgd, Version=17.1.0.0, Culture=neutral, PublicKeyToken=null]] GetRXClass() AS Autodesk.AutoCAD.Runtime.RXClass GetType() AS System.Type GetXDataForApplication(String) AS Autodesk.AutoCAD.DatabaseServices.ResultBuffer HasPersistentReactor(ObjectId) AS System.Boolean InitializeLifetimeService() AS System.Object QueryX(RXClass) AS System.IntPtr RemoveField() AS Autodesk.AutoCAD.DatabaseServices.ObjectId RemoveField(String) AS Autodesk.AutoCAD.DatabaseServices.ObjectId SetAttributes(DrawableTraits) AS System.Int32 SetField(Field) AS Autodesk.AutoCAD.DatabaseServices.ObjectId SetField(String,Field) AS Autodesk.AutoCAD.DatabaseServices.ObjectId SetFromStyle() AS System.Boolean ToString() AS System.String UpgradeFromNotify() AS System.Boolean ViewportDrawLogicalFlags(ViewportDraw) AS System.Int32 WblockClone(RXObject,IdMapping,Boolean) AS Autodesk.AutoCAD.DatabaseServices.DBObject WorldDraw(WorldDraw) AS System.Boolean X(RXClass) AS System.IntPtr 属性: AcadObject AS System.Object 可读不可写 Annotative AS Autodesk.AutoCAD.DatabaseServices.AnnotativeStates 可读可写 AutoDelete AS System.Boolean 可读可写 BigFontFileName AS System.String 可读可写 ClassID AS System.Guid 可读不可写 Database AS Autodesk.AutoCAD.DatabaseServices.Database 可读不可写 Drawable AS Autodesk.AutoCAD.GraphicsInterface.Drawable 可读不可写 DrawableType AS Autodesk.AutoCAD.GraphicsInterface.DrawableType 可读不可写 ExtensionDictionary AS Autodesk.AutoCAD.DatabaseServices.ObjectId 可读不可写 FileName AS System.String 可读可写 FlagBits AS System.Byte 可读可写 Font AS Autodesk.AutoCAD.GraphicsInterface.FontDescriptor 可读可写 Handle AS Autodesk.AutoCAD.DatabaseServices.Handle 可读不可写 HasFields AS System.Boolean 可读不可写 HasSaveVersionOverride AS System.Boolean 可读可写 Id AS Autodesk.AutoCAD.DatabaseServices.ObjectId 可读不可写 IsAProxy AS System.Boolean 可读不可写 IsCancelling AS System.Boolean 可读不可写 IsDependent AS System.Boolean 可读不可写 IsDisposed AS System.Boolean 可读不可写 IsErased AS System.Boolean 可读不可写 IsEraseStatusToggled AS System.Boolean 可读不可写 IsModified AS System.Boolean 可读不可写 IsModifiedGraphics AS System.Boolean 可读不可写 IsModifiedXData AS System.Boolean 可读不可写 IsNewObject AS System.Boolean 可读不可写 IsNotifyEnabled AS System.Boolean 可读不可写 IsNotifying AS System.Boolean 可读不可写 IsObjectIdsInFlux AS System.Boolean 可读不可写 IsPersistent AS System.Boolean 可读不可写 IsReadEnabled AS System.Boolean 可读不可写 IsReallyClosing AS System.Boolean 可读不可写 IsResolved AS System.Boolean 可读不可写 IsShapeFile AS System.Boolean 可读可写 IsTransactionResident AS System.Boolean 可读不可写 IsUndoing AS System.Boolean 可读不可写 IsVertical AS System.Boolean 可读可写 IsWriteEnabled AS System.Boolean 可读不可写 MergeStyle AS Autodesk.AutoCAD.DatabaseServices.DuplicateRecordCloning 可读可写 Name AS System.String 可读可写 ObjectBirthVersion AS Autodesk.AutoCAD.DatabaseServices.FullDwgVersion 可读不可写 ObjectId AS Autodesk.AutoCAD.DatabaseServices.ObjectId 可读不可写 ObliquingAngle AS System.Double 可读可写 OwnerId AS Autodesk.AutoCAD.DatabaseServices.ObjectId 可读可写 PaperOrientation AS Autodesk.AutoCAD.DatabaseServices.PaperOrientationStates 可读不可写 PriorSize AS System.Double 可读可写 TextSize AS System.Double 可读可写 UndoFiler AS Autodesk.AutoCAD.DatabaseServices.DwgFiler 可读不可写 UnmanagedObject AS System.IntPtr 可读不可写 XData AS Autodesk.AutoCAD.DatabaseServices.ResultBuffer 可读可写 XScale AS System.Double 可读可写 -------------------------------- 类:Autodesk.AutoCAD.DatabaseServices.TextVerticalMode:System.Enum 函数: CompareTo(Object) AS System.Int32 Equals(Object) AS System.Boolean GetHashCode() AS System.Int32 GetType() AS System.Type GetTypeCode() AS System.TypeCode ToString() AS System.String ToString(IFormatProvider) AS System.String ToString(String,IFormatProvider) AS System.String ToString(String) AS System.String 字段: TextBase AS TextVerticalMode TextBottom AS TextVerticalMode TextTop AS TextVerticalMode TextVerticalMid AS TextVerticalMode value__ AS Int32
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值