ObjectARX AcDbSortentsTable设置对象的绘图顺序 moveToTop moveToBottom

作者: admin 分类: C++,CAD,ObjectARX 发布时间: 2020-07-08 22:52
static AcDbSortentsTable* get_sortents_table_of(AcDbEntity *pEnt)
{
AcDbObjectId owner_id = pEnt->ownerId();
if (AcDbObjectId::kNull == owner_id)
{
return NULL;
}
AcDbBlockTableRecord *pRec;
if (Acad::eOk != acdbOpenObject(pRec, owner_id, AcDb::kForRead))
{
return NULL;
}
AcDbObjectId ext_id = pRec->extensionDictionary();
if (AcDbObjectId::kNull == ext_id)
{
if (Acad::eOk != pRec->upgradeOpen())
{
pRec->close();
return NULL;
}
pRec->createExtensionDictionary();
ext_id = pRec->extensionDictionary();
if (AcDbObjectId::kNull == ext_id)
{
pRec->close();
return NULL;
}
}
AcDbDictionary* pExt;
Acad::ErrorStatus es = acdbOpenObject(pExt, ext_id, AcDb::kForRead);
pRec->close();
if (Acad::eOk != es)
{
return NULL;
}
AcDbObject *pObj;
if (Acad::eOk != pExt->getAt(_T("ACAD_SORTENTS"), pObj, AcDb::kForWrite))
{
if (Acad::eOk != pExt->upgradeOpen())
{
pExt->close();
return NULL;
}
AcDbSortentsTable *pSt = new AcDbSortentsTable;
if (NULL == pSt)
{
pExt->close();
return NULL;
}
AcDbObjectId new_id;
if (Acad::eOk != pExt->setAt(_T("ACAD_SORTENTS"), pSt, new_id))
{
delete pSt;
pExt->close();
return NULL;
}
pSt->setBlockId(owner_id);
pObj = pSt;
}
pExt->close();
if (!pObj->isKindOf(AcDbSortentsTable::desc()))
{
pObj->close();
return NULL;
}
return (AcDbSortentsTable*)pObj;
}

使用方法

//设置绘图顺序为最靠上
AcDbSortentsTable *pSt = get_sortents_table_of(pPoly);
if (NULL != pSt)
{
AcDbObjectIdArray arrIds;
arrIds.append(pPoly->objectId());
pSt->moveToTop(arrIds);
pSt->close();
}

另外注意若pEnt添加到数据库的顺序,也影响了顺序,即默认情况下后添加到数据库的,顺序靠上。添加到数据库后,是否立即显示参见上一篇的pEnt->close()和pEnt->draw()

参考代码:

CAD drawOrder

2008 – 06 – 05 14:31

sortens.cpp

#include "StdAfx.h"

#include "StdArx.h"

#include "sorttab.h"

#include "Sortens.h"

AcDbSortentsTable* get_sortents_table_of(AcDbEntity *pEnt)

{

AcDbObjectId owner_id = pEnt->ownerId();

if (AcDbObjectId::kNull == owner_id)

{

return NULL;

}

AcDbBlockTableRecord *pRec;

if (Acad::eOk != acdbOpenObject(pRec, owner_id, AcDb::kForRead))

{

return NULL;

}

AcDbObjectId ext_id = pRec->extensionDictionary();

if (AcDbObjectId::kNull == ext_id)

{

if (Acad::eOk != pRec->upgradeOpen())

{

pRec->close();

return NULL;

}

pRec->createExtensionDictionary();

ext_id = pRec->extensionDictionary();

if (AcDbObjectId::kNull == ext_id)

{

pRec->close();

return NULL;

}

}

AcDbDictionary* pExt;

Acad::ErrorStatus es = acdbOpenObject(pExt, ext_id, AcDb::kForRead);

pRec->close();

if (Acad::eOk != es)

{

return NULL;

}

AcDbObject *pObj;

if (Acad::eOk != pExt->getAt(_T("ACAD_SORTENTS"), pObj, AcDb::kForWrite))

{

if (Acad::eOk != pExt->upgradeOpen())

{

pExt->close();

return NULL;

}

AcDbSortentsTable *pSt = new AcDbSortentsTable;

if (NULL == pSt)

{

pExt->close();

return NULL;

}

AcDbObjectId new_id;

if (Acad::eOk != pExt->setAt(_T("ACAD_SORTENTS"), pSt, new_id))

{

delete pSt;

pExt->close();

return NULL;

}

pSt->setBlockId(owner_id);

pObj = pSt;

}

pExt->close();

if (!pObj->isKindOf(AcDbSortentsTable::desc()))

{

pObj->close();

return NULL;

}

return (AcDbSortentsTable*)pObj;

}

void setSortentsBits(int bits)

{

resbuf rb;

rb.restype = RTSHORT;

rb.resval.rint = bits;

acedSetVar("SORTENTS", &rb);

}

void configureSortents()

{

resbuf rb;

const int nSortentsMask = (1 | 2 | 4 | 8 | 16 | 32 | 64);

acedGetVar("SORTENTS", &rb);

if (nSortentsMask != (rb.resval.rint & nSortentsMask))

setSortentsBits(rb.resval.rint | nSortentsMask);

}

void MSSendBack(AcDbObjectId ent_id)

{

configureSortents();

AcDbEntity *pEnt;

if (Acad::eOk != acdbOpenObject(pEnt, ent_id, AcDb::kForRead))

return;

AcDbSortentsTable *pSt = get_sortents_table_of(pEnt);

pEnt->close();

if (NULL == pSt)

return;

AcDbObjectIdArray entity_array;

entity_array.append(ent_id);

pSt->moveToBottom(entity_array);

pSt->close();

}

sortens.h

///////////////////////// ////////////////////////////////////////////

/////////////////Sortens.h////// /////////////////////////////////////

#include "sorttab.h"

AcDbSortentsTable* get_sortents_table_of(AcDbEntity *pEnt);

void setSortentsBits(int bits);

void configureSortents();

void MSSendBack(AcDbObjectId ent_id);

how to use sample :

//select all object on this layer

ads_name ssname1;

struct resbuf *eb1;

ads_name ename;

eb1 = acutBuildList(-4, "", -4, "", -4, "or>", 0);

//select single objects

acedSSGet("X", NULL, NULL, eb1, ssname1);

//for acedSSGet

long ilast;

// Find the index of the last entity in sset.

acedSSLength(ssname1, &ilast);

AcDbObjectId SolidId;

AcDbObjectId

Array IdArray;

for (int i = 0; i < ilast; i++)

{

acedSSName(ssname1, 0, ename);

// Get the insert's block table record and compare its name

// to make sure we've got the right block. If so, set the layer

if (acdbGetObjectId(SolidId, ename) == Acad::eOk)

MSSendBack(SolidId);

}

晓东lovearx

实际上就是获得

1、如果你的实体在模型空间,就是获得模型空间对象扩展辞典里面的ACAD_SORTENTS
2、如果你要调整块内的显示顺序,就是获得AcDbBlockTableRecord   的扩展辞典里面的ACAD_SORTENTS

下面函数打开块表记录的ACAD_SORTENTS对象写,

执行完参数后记得CLOSE返回的对象。

下面函数 如果 块表记录没有ACAD_SORTENTS 就创建,如果有就得到指针打开写,返回。

AcDbSortentsTable * XdDbUtils::getSortentsTable( AcDbBlockTableRecord * pRec )
{
        if (!pRec)
                return NULL;
        Acad::ErrorStatus es;
        AcDbObjectId ext_id = pRec->extensionDictionary();
        if (AcDbObjectId::kNull == ext_id)
        {
                pRec->upgradeOpen();
                es = pRec->createExtensionDictionary();
                if (es != eOk)
                        return NULL;
                pRec->downgradeOpen();
                ext_id = pRec->extensionDictionary();
                if (AcDbObjectId::kNull == ext_id)
                {
                        return NULL;
                }
                pRec->downgradeOpen();
        }
        AcDbDictionary *pExt;
        es = acdbOpenObject( pExt, ext_id, AcDb::kForRead );
        if (Acad::eOk != es)
                return NULL;
        AcDbObject *pObj;
        if (Acad::eOk != pExt->getAt( _T("ACAD_SORTENTS"), pObj, AcDb::kForWrite ))
        {
                if (Acad::eOk != pExt->upgradeOpen())
                {
                        pExt->close();
                        return NULL;
                }
                AcDbSortentsTable *pSt = new AcDbSortentsTable;
                if (NULL == pSt)
                {
                        pExt->close();
                        return NULL;
                }
                AcDbObjectId new_id;
                if (Acad::eOk != pExt->setAt( _T("ACAD_SORTENTS"), pSt, new_id ))
                {
                        delete pSt;
                        pExt->close();
                        return NULL;
                }
                pSt->setBlockId( pRec->objectId() );
                pObj = pSt;
        }
        pExt->close();
        if (!pObj->isKindOf( AcDbSortentsTable::desc() ))
        {
                pObj->close();
                return NULL;
        }
        return (AcDbSortentsTable*)pObj;
}

你要先获得当前块表记录的sortents对象,而不是直接用这个类

AcDbSortentsTable *pSt = getSortentsTable( ownerId);
if (NULL == pSt)
        return ;
es=pSt->moveToBottom(ids );
pSt->close();

sortents对象保存在块表记录(模型空间、图纸空间或者图块的扩展辞典的ACAD_SORTENTS子辞典下

114213ru2l0qlllp2qlxqe.png

https://forums.autodesk.com/t5/objectarx/aceddraworderinherit/td-p/5541384

Acad::ErrorStatus changeDrawOrder(AcDbObjectId parent, AcDbObjectIdArray &childArray, AcEdDrawOrderCmdType variant)
{
   if (childArray.isEmpty()) return Acad::eInvalidInput;
   Acad::ErrorStatus es = Acad::eOk;
   AcDbSortentsTable *pSortTab = NULL;
   AcDbObjectId spaceId = AcDbObjectId::kNull;
   AcDbEntityPointer pEnt(childArray.first(),AcDb::kForRead);
   if (pEnt.openStatus() == Acad::eOk) 
   {
      spaceId = pEnt->ownerId();
      pEnt->close();
   }
   if (!spaceId.isNull()) 
   {
      AcDbBlockTableRecordPointer pBTR(spaceId,AcDb::kForRead);
      if (pBTR.openStatus() == Acad::eOk) 
      {
         if (pBTR->getSortentsTable(pSortTab, AcDb::kForWrite, true) == Acad::eOk) 
         {
            switch (variant)
            {
               case kDrawOrderBottom:
                  es = pSortTab->moveToBottom(childArray);
                  break;
					
               case kDrawOrderTop:
                  es = pSortTab->moveToTop(childArray);
                  break;
						
               case kDrawOrderBelow:
                  es = pSortTab->moveBelow(childArray,parent);
                  break;
						
               case kDrawOrderAbove:
                  es = pSortTab->moveAbove(childArray,parent);
                  break;
            }
            pSortTab->close();
         }
      }
   }
   return es;
}

and a sample of usage

AcDbObjectId parent;
AcDbObjectIdArray childArray;

ads_name ent, ents;
AcGePoint3d pt;
if (acedEntSel(_T("\nparent: "),ent,asDblArray(pt)) != RTNORM) return;
acdbGetObjectId(parent,ent);

switch(acedSSGet(NULL,NULL,NULL,NULL,ents))
{
  case RTERROR:
  case RTCAN:
    return;
}
		
long len = 0L;
int res = acedSSLength(ents, &len);
if(res != RTNORM || len == 0) return;
for (int i = 0; i < len; i++)
{
  AcDbObjectId eId;
  ads_name one_ent;
  if (ads_ssname(ents,i,one_ent)!=RTNORM)continue;
  if(acdbGetObjectId(eId, one_ent)!= Acad::eOk)continue;
  childArray.append(eId);
}
acedSSFree(ents);

// move "childArray" below "parent"
// if you use "top" or "bottom" variant parent can be NULL
if (Acad::eOk != changeDrawOrder(parent, childArray, kDrawOrderBelow))
{
  acutPrintf(_T("\n** cant do this"));
}

thank  you ,

here is my code,you kan test it

   // Add your code for command vcArxP._SelLayerBottom here
  

ads_name entName;
  ads_point entpoint;
  if (acedEntSel(_T("\nlayer:"),entName,entpoint)!=RTNORM)
  {
   return;
  }
  AcDbObjectId layerId;
  acdbGetObjectId(layerId,entName);
  AcDbEntity *pEnt;
  acdbOpenObject(pEnt,layerId,AcDb::kForWrite);
  TCHAR *layerName=pEnt->layer();
  pEnt->close();

 

  struct resbuf *rb;
  ads_name ssname;
  rb=acutBuildList(8,layerName,RTNONE);

    int rc=acedSSGet(_T("X"),NULL,NULL,rb,ssname);
  AcDbObjectIdArray objIds;
  if (rc!=RTNORM)
  {
   acutRelRb(rb);
      return;
  }

  long length;
  acedSSLength(ssname,&length);
  acutPrintf(_T("\nlayer%sall%d个"),layerName,length);
  for (int i=0;i<length;i++)
  {
   ads_name ent;
   acedSSName(ssname,i,ent);
   AcDbObjectId objId;
   acdbGetObjectId(objId,ent);
   objIds.append(objId);

  }
  changeDrawOrder(NULL,objIds,kDrawOrderTop);
  //acedDrawOrderInherit(NULL,objIds,::kDrawOrderTop);
  acedSSFree(ssname);
   acutDelString(layerName);
  if (rb!=NULL)
  {
   acutRelRb(rb);
  }

your code works fine. for example i have 5 objects. one of them (black) has  different layer from others

sortdraworder.jpg

 anyway, es =  changeDrawOrder(… 

if es == Acad::eOk, function works as expected. so, if your results a different from my, check "es"

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!

发表评论

标签云