明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 2063|回复: 10

怎么亮显块内单个实体

[复制链接]
发表于 2016-6-1 13:29 | 显示全部楼层 |阅读模式
本帖最后由 czx1234567 于 2016-6-1 13:31 编辑

请教,怎么亮显块参照内的单个实体(不是子实体),如文本,线段等。
Objectarx帮助文件里有亮显嵌套块参照子实体的例子,但那个似乎不能用于文本等简单实体的亮显。
下面的代码能获得块内实体的指针,不知道为什么不能亮显。
        ads_name ename;
        ads_matrix adsmat;
        struct resbuf *insStack;
        acedNEntSelP(NULL, ename, pickpoint, TRUE, adsmat, &insStack);
        AcDbObjectId objectId;
        acdbGetObjectId(objectId, ename);
        AcDbEntity *pEnt = NULL;
        acdbOpenAcDbEntity(pEnt, objectId, AcDb::kForWrite);
        pEnt ->highlight();
 楼主| 发表于 2016-6-2 23:00 | 显示全部楼层
似乎是个难题。搜了几天没搜到答案。但应该是可以实现的。
 楼主| 发表于 2016-6-3 14:07 | 显示全部楼层
问题终于得到解决。原来是我没仔细看懂Objectarx帮助文件中的实例。很简单几行代码实现块内实体亮显功能,关键是弄懂AcDbFullSubentPath类的构造。

void HighlightEntityInBlock(ads_point pickpoint, bool bHighlight)
{
        ads_name ename;
        ads_matrix adsmat;
        struct resbuf *insStack;
        acedNEntSelP(NULL, ename, pickpoint, TRUE, adsmat, &insStack);
        AcDbObjectId selId;
        acdbGetObjectId(selId, ename);

        ads_name sset;
        acedSSGet(NULL, pickpoint, NULL, NULL, sset);
        acedSSName(sset, 0, ename);
        AcDbObjectId blRefId;
        acdbGetObjectId(blRefId, ename);
        AcDbEntity *pEnt = NULL;
        acdbOpenAcDbEntity(pEnt, blRefId, AcDb::kForRead);
        AcDbBlockReference *pBlock = AcDbBlockReference::cast(pEnt);
       
        AcDbFullSubentPath subPath;
        subPath.objectIds().append(blRefId);
        subPath.objectIds().append(selId);
        if (bHighlight)
                pBlock->highlight(subPath);
        else
                pBlock->unhighlight(subPath);
        pBlock->close();
}
 楼主| 发表于 2016-6-3 15:26 | 显示全部楼层
上面的代码只能显示单层块参照实体。对于多层嵌套块参照可以用下面的代码。

void CAddToDwg::HighlightEntityInBlock(ads_point pickpoint, bool bHighlight)
{
        ads_name ename;
        ads_matrix adsmat;
        struct resbuf *insStack;
        acedNEntSelP(NULL, ename, pickpoint, TRUE, adsmat, &insStack);
        AcDbObjectId selId;
        acdbGetObjectId(selId, ename);

        ads_name sset;
        acedSSGet(NULL, pickpoint, NULL, NULL, sset);
        acedSSName(sset, 0, ename);
        AcDbObjectId blRefId;
        acdbGetObjectId(blRefId, ename);

        int count = 0;
        struct resbuf *rbIter = insStack;
        AcDbObjectId *idArray = new AcDbObjectId[100];
        AcDbObjectId objectId;
        while (rbIter != NULL && count <100)
        {
                ename[0] = rbIter->resval.rlname[0];
                ename[1] = rbIter->resval.rlname[1];
                acdbGetObjectId(objectId, ename);
                idArray[count] = objectId;
                rbIter = rbIter->rbnext;
                count++;
        }
        acutRelRb(insStack);

        AcDbFullSubentPath subPath;
        for (int i = count; i > 0; i--)
        {
                subPath.objectIds().append(idArray[i-1]);
        }               
        AcDbEntity *pEntSel = NULL;
        acdbOpenAcDbEntity(pEntSel, selId, AcDb::kForRead);
        if (pEntSel ->isKindOf(AcDbAttribute::desc()))
                subPath.objectIds().append(pEntSel ->ownerId());
        pEntSel ->close();
        subPath.objectIds().append(selId);

        AcDbEntity *pEnt = NULL;
        acdbOpenAcDbEntity(pEnt, blRefId, AcDb::kForRead);
        AcDbBlockReference *pBlock = AcDbBlockReference::cast(pEnt);
        if (bHighlight)
                pBlock->highlight(subPath);
        else
                pBlock->unhighlight(subPath);
        pBlock->close();
}
 楼主| 发表于 2016-6-6 12:33 | 显示全部楼层
本帖最后由 czx1234567 于 2016-6-6 12:38 编辑

还可以简化

void CAddToDwg::HighlightEntityInBlock(ads_point pickpoint, bool bHighlight)
{
        ads_name ename;
        ads_matrix adsmat;
        struct resbuf *insStack;
        acedNEntSelP(NULL, ename, pickpoint, TRUE, adsmat, &insStack);
        AcDbObjectId selId;
        acdbGetObjectId(selId, ename);

        //ads_name sset;
        //acedSSGet(NULL, pickpoint, NULL, NULL, sset);
        //acedSSName(sset, 0, ename);
        //AcDbObjectId blRefId;
        //acdbGetObjectId(blRefId, ename);


        int count = 0;
        struct resbuf *rbIter = insStack;
        AcDbObjectId *idArray = new AcDbObjectId[100];
        AcDbObjectId objectId;
        while (rbIter != NULL && count <100)
        {
                ename[0] = rbIter->resval.rlname[0];
                ename[1] = rbIter->resval.rlname[1];
                acdbGetObjectId(objectId, ename);
                idArray[count] = objectId;
                rbIter = rbIter->rbnext;
                count++;
        }
        acutRelRb(insStack);

        AcDbFullSubentPath subPath;
        for (int i = count; i > 0; i--)
        {
                subPath.objectIds().append(idArray[i-1]);
        }               
        AcDbEntity *pEntSel = NULL;
        acdbOpenAcDbEntity(pEntSel, selId, AcDb::kForRead);
        if (pEntSel ->isKindOf(AcDbAttribute::desc()))
                subPath.objectIds().append(pEntSel ->ownerId());
        pEntSel ->close();
        subPath.objectIds().append(selId);

        AcDbEntity *pEnt = NULL;
        acdbOpenAcDbEntity(pEnt, subPath.objectIds().first(), AcDb::kForRead);
        //AcDbBlockReference *pBlock = AcDbBlockReference::cast(pEnt);
        if (bHighlight)
                pEnt->highlight(subPath);
        else
                pEnt->unhighlight(subPath);
        pEnt->close();
}
发表于 2016-6-20 15:41 | 显示全部楼层
多谢,lz知道如何写自定义实体的选择子实体,类似于 多段线中 夹角标注时可以选择多段线的2个边进行操作
发表于 2016-7-3 17:52 | 显示全部楼层
czx1234567 发表于 2016-6-3 15:26
上面的代码只能显示单层块参照实体。对于多层嵌套块参照可以用下面的代码。

void CAddToDwg::HighlightE ...

楼主,我也被类似的问题困扰了好一阵了,是怎样重载AcDbEntity的virtual Acad::ErrorStatus subHighlight,不知道你清不清楚
发表于 2016-7-28 20:44 | 显示全部楼层
谢谢楼主分享,好经验
发表于 2018-8-8 13:23 | 显示全部楼层
下载试试,谢谢源码!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-3-29 20:06 , Processed in 0.232728 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表