ObjectARX
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Purge nested anonymous Blocks

2 REPLIES 2
Reply
Message 1 of 3
SCTINFORMATICA
773 Views, 2 Replies

Purge nested anonymous Blocks

Hi Comm,

 

I wrote this function to purge anonymous blocks. It works but only at top level:  it doesn't work with nested blocks.

If I try to loop the function until the ObjectIdArray is empty, it seems to go well, but if you use AUDIT on DWG after the "purge execution" the nested blocks re-appear.

 


Acad::ErrorStatus Grazie::purge()
{
    Acad::ErrorStatus es;
    AcDbObjectIdArray ids;
    AcDbObjectId id;

    CString nome=L"";
    AcDbObjectId tblRecId;

    AcDbDatabase *pDbUse=acdbHostApplicationServices()->workingDatabase();
    ids.setLogicalLength(0).setPhysicalLength(0);

    AcDbBlockTable *pBlockTable;
    es=acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForWrite);

    AcDbBlockTableIterator* tblIter;
    es = pBlockTable->newIterator(tblIter);
    if (es == Acad::eOk)
    {
      // walk table and just collect all the objIds
      // of the entries
        for (; !tblIter->done(); tblIter->step())
        {
            AcDbBlockTableRecord* blkRec;
            es = tblIter->getRecord(blkRec, AcDb::kForWrite);
            if (es == Acad::eOk)
            {
                //if(blkRec->isKindOf(AcDbBlockReference::desc()))
                {
                    if (blkRec->isAnonymous())
                    {
                        ACHAR* locName;
                        blkRec->getName(locName);
                        id=blkRec->id();
                        ids.append(id);
  
                    }
                }
                blkRec->close();
            }
        }
        delete tblIter;
    }
    pBlockTable->close();

    es=pDbUse->purge(ids);

    es = pBlockTable->newIterator(tblIter);
    if (es == Acad::eOk)
    {
      // walk table and just collect all the objIds
      // of the entries
        for (; !tblIter->done(); tblIter->step())
        {
            AcDbBlockTableRecord* blkRec;
            es = tblIter->getRecord(blkRec, AcDb::kForWrite);
            if (es == Acad::eOk)
            {
                //if(blkRec->isKindOf(AcDbBlockReference::desc()))
                {
                    if (blkRec->isAnonymous())
                    {
                        ACHAR* locName;
                        blkRec->getName(locName);
                        id=blkRec->id();
                        if(ids.find(id)>=0)
                        {
                            nome=L"";
                            nome=locName;
//                            if(nome.Find(L"*D")==0 || nome.Find(L"*U")==0)
                                es=blkRec->erase();
                        }
                    }
                }
                blkRec->close();
            }
        }
        delete tblIter;
    }
    pBlockTable->close();
    ids.setLogicalLength(0).setPhysicalLength(0);

    return es;

}

 

What can I do to Fix the problem?

Thank You,

 

Regards,

 

Mario

SCT Informatica
2 REPLIES 2
Message 2 of 3
Anonymous
in reply to: SCTINFORMATICA

Hi,

 

this is very simple. Just run an loop until no purgeable ID's were found.

Message 3 of 3
tbrammer
in reply to: SCTINFORMATICA

It is not a good idea to erase entries of the blocktable during an iterator loop. Although I'm not sure whether this causes your problem. You already have the AcDbObjectId s collected, so you can write the second part of your function like this:

 

	int i, nCount = ids.length();
	for (i = 0; i < nCount; ++i)
	{
		AcDbBlockTableRecord* blkRec=NULL;
		if ( (es=acdbOpenObject(blkRec, ids[i], AcDb::kForWrite)) == Acad::eOk )
		{
			es = blkRec->erase();
			blkRec->close();		
		}
	}

 

Besides that the second call of   es = pBlockTable->newIterator(tblIter);   is carried out after pBlockTable was closed!

 

By the way: If you use a non-const ACHAR* for

            ACHAR* locName;
            blkRec->getName(locName);

You have to release the memory for it with acutDelString(locName)! I recomment using   const ACHAR *locName=NULL;  instead. You don't have to release the memory than.


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost