【CAD二次开发】-ObjectARX-设置自定义对象的子实体层

 

  声明:本文的为翻译文章,原文地址为:http://adndevblog.typepad.com/autocad/objectarx/

  有时候我们希望将自定义对象的子实体设置为特定图层。当相应的图层发生变化(例如可见性,颜色等)时,实体将相应地更新。

  解决方案非常简单。 worldDraw-> subEntityTraits()。setLayer允许我们为特定图层指定自定义对象的特定基元。 此方法将AcGiSubEntityTraits对象设置为使用layerId指定要在其上绘制图形基元的图层,直到下一次调用此函数,或者执行worldDraw()或viewportDraw()结束。

第一步:创建函数:drawEdges

 使用ObjectARX向导创建一个项目:asdkpolyobj

在入口文件acrxEntryPoint.cpp中的类中 class CasdkpolyobjApp 创建函数:drawEdges:

	static Acad::ErrorStatus drawEdges(const AsdkPoly* poly,
		AcGiWorldDraw*    worldDraw,
		AcGiViewportDraw* vportDraw)
	{

	}

类AsdkPoly需要添加头文件:

#include "poly.h"

详细分析;

类 AcGiWorldDraw:

描述:

  AcGiWorldDraw类提供了一种功能,它能够生成对不同的viewport没有变化的几何图形。在不同的viewport中,几何图形可能看起来不同(由于不同的缩放因子、视点等),但是只生成了一组几何图形,然后由AutoCAD对所有不同的viewport进行调整。

注释:

  这个类可以派生出来,创建您自己的类,以传递给实体的worldDraw()方法。如果您还从acgiworld几何学中派生出来,并使用您自己的实现来覆盖它的方法,并使用两个派生类的对象,那么您将能够获得一个实体的图形信息,而无需直接访问实体的底层代码。有一种情况证明这是有用的,那就是当需要AutoCAD固体的面几何时。

 函数drawEdges的实现:

第二步:获取特定的图层ID

  将多边形的每条边画成一条直线。我们可以画出整个多边形是一个polyline,但是我们想要附加子实体特征(例如,它是哪一条线)到那一条line将被捕获。

  因为我们用直线画出多边形线,我们也有控制设置每条line的线型和颜色(通过子实体的特征),但我们不会有那样的fancy。

获得 layers ID的代码实现:

	Acad::ErrorStatus es = Acad::eOk;


    AcDbObjectId testLayerId = AcDbObjectId::kNull; 
	AcDbObjectId zeroLayerId = AcDbObjectId::kNull;

	AcDbLayerTable* lTable = NULL;  
	AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase(); 
	Acad::ErrorStatus layer_table_es = pDb->getSymbolTable(lTable, AcDb::kForRead); 

	if (Acad::eOk == layer_table_es && lTable)
	{   
		if (lTable->getAt(_T("MyTestLayer"), testLayerId) != Acad::eOk) 
			::acutPrintf(_T("ERROR Getting MyTestLayer\\n"));  
		if (lTable->getAt(_T("0"), zeroLayerId) != Acad::eOk)
			::acutPrintf(_T("ERROR Getting 0 Layer\\n"));

		lTable->close(); 
	}

函数getAt:

语法:

Acad::ErrorStatus getAt(
    const ACHAR* entryName, 
    AcDbObjectId& recordId, 
    bool getErasedRecord = false
) const;

参数: 

const ACHAR* entryName 

搜索的输入名称

AcDbObjectId& recordId 

带有记录的客观记录和名称入口名称

bool getErasedRecord = false 

输入bool指示是否要“查找”一个擦除的记录

描述:

  如果找到匹配的记录,这个函数返回值recordId中由entryName指定的记录的AcDbObjectId。如果getErasedRecord是正确的,那么与擦除记录匹配是可能的。

第三步:获得顶点数组

    AcGePoint3dArray vertexArray;
    if ((es = poly->getVertices3d(vertexArray)) != Acad::eOk) {
        return es;
    }

第四步:将指定的边设置为图层MyTestLayer

		AcGePoint3d ptArray[2];
		for (int i = 0; i < vertexArray.length() - 1; i++) {
			if (worldDraw != NULL) {

				if (i % 3 == 0) {
					//如果是一条指定的边,设置它为图层MyTestLayer
					if (!testLayerId.isNull())
						worldDraw->subEntityTraits().setLayer(testLayerId);
				}
				else {
					//其他的边,设置它们到图层0
					if (!zeroLayerId.isNull())
						worldDraw->subEntityTraits().setLayer(zeroLayerId);
				}
				worldDraw->subEntityTraits().setSelectionMarker(i + 1);
			}
			else {
				assert(Adesk::kFalse);
				//vportDraw->subEntityTraits().setSelectionMarker(i + 1);
			}

			ptArray[0] = vertexArray[i];
			ptArray[1] = vertexArray[i + 1];

			if (worldDraw != NULL) {
				worldDraw->geometry().polyline(2, ptArray);
			}
			else {
				assert(Adesk::kFalse);
				//vportDraw->geometry().polylineDc(2, ptArray);
			}
		}

完整源代码:

//设置自定义对象的子实体层
	static Acad::ErrorStatus drawEdges(const AsdkPoly* poly,
		AcGiWorldDraw* worldDraw,
		AcGiViewportDraw* vportDraw)
	{
		Acad::ErrorStatus es = Acad::eOk;
		AcDbObjectId testLayerId = AcDbObjectId::kNull;
		AcDbObjectId zeroLayerId = AcDbObjectId::kNull;

		AcDbLayerTable* lTable = NULL;
		AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();
		Acad::ErrorStatus layer_table_es = pDb->getSymbolTable(lTable, AcDb::kForRead);

		if (Acad::eOk == layer_table_es && lTable)
		{
			if (lTable->getAt(TEXT("MyTestLayer"), testLayerId) != Acad::eOk)
				::acutPrintf(TEXT("ERROR Getting MyTestLayer\\n"));
			if (lTable->getAt(TEXT("0"), zeroLayerId) != Acad::eOk)
				::acutPrintf(TEXT("ERROR Getting O Layer\\n"));

			lTable->close();
		}

		AcGePoint3dArray vertexArray;
		if ((es = poly->getVertices3d(vertexArray)) != Acad::eOk) {
			return es;
		}

		AcGePoint3d ptArray[2];
		for (int i = 0; i < vertexArray.length() - 1; i++) {
			if (worldDraw != NULL) {

				if (i % 3 == 0) {
					//如果是一条指定的边,设置它为图层MyTestLayer
					if (!testLayerId.isNull())
						worldDraw->subEntityTraits().setLayer(testLayerId);
				}
				else {
					//其他的边,设置它们到图层0
					if (!zeroLayerId.isNull())
						worldDraw->subEntityTraits().setLayer(zeroLayerId);
				}
				worldDraw->subEntityTraits().setSelectionMarker(i + 1);
			}
			else {
				assert(Adesk::kFalse);
				//vportDraw->subEntityTraits().setSelectionMarker(i + 1);
			}

			ptArray[0] = vertexArray[i];
			ptArray[1] = vertexArray[i + 1];

			if (worldDraw != NULL) {
				worldDraw->geometry().polyline(2, ptArray);
			}
			else {
				assert(Adesk::kFalse);
				//vportDraw->geometry().polylineDc(2, ptArray);
			}
		}
		return es;
	}

<全文完>

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容