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

Unexpected block reference counts?

8 REPLIES 8
Reply
Message 1 of 9
cadMeUp
591 Views, 8 Replies

Unexpected block reference counts?

Hello All,

I am using AutoCAD 2005, building on VS .NET 2002 for ObjectARX. I am running into a confusing situation with block reference counts. Here is the scenario:

I create 2 new drawings. In drawing 1 I create a block and give it a name of, lets say 'TEST_BLOCK_1' and create the block as normal. (The blocks that I normally use have attributes but I am using just any kind of a simple block for example). So in this drawing 1 there is 1 block reference that I can see on screen. I inserted the block reference just 1 time. Now I select the block reference in drawing 1 and do a CTRL + C to copy it to the clipboard. I switch to drawing 2 that is a clean database with no block definitions. I paste the block reference from the clipboard into drawing 2 and there is the 1 block reference on the screen. Note that I only paste it only once and make no other copies of the block.

Now, in my ObjectARX routine, I am getting the blocktablerecord of 'TEST_BLOCK_1' and counting the number of references that are in the database for that blocktablerecord. In drawing 1 I get a count of 1, in drawing 2 I get a count of 2.

Seems very strange! I have also had some other issues when working with blockreferences, but did not keep track of them so I am unable to describe them here.

Has anyone had this kind of issue to deal with? Seems like a bug to me but I don't want to jump on that when I know I could be doing something wrong, but I am not doing anything out of ordinary.

Any help on this matter would be appreciated!

Thanks!

Larry
8 REPLIES 8
Message 2 of 9
Anonymous
in reply to: cadMeUp

It is hard to know without seeing any code at all, how are you implementing
the usage of getBlockReferenceIds() ?
Message 3 of 9
cadMeUp
in reply to: cadMeUp

Hello Luis,

Sorry I should have provided some:

int GetBlockObjectCount(const CString& name)
{
AcDbBlockTable* pBlockTab = NULL;
AcDbDatabase* pCurDB = acDocManager->curDocument()->database();
pCurDB->getBlockTable(pBlockTab, AcDb::kForRead);

AcDbBlockTableRecord* pTabRec = NULL;
if(pBlockTab->getAt(name, pTabRec, AcDb::kForRead) != Acad::eOk)
{
pBlockTab->close();
return -1;
}
pBlockTab->close();

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

AcDbObjectIdArray idArray;
pTabRec->getBlockReferenceIds(idArray);
pTabRec->close();

if(idArray.length() == 0)
return -1;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

for(int index = 0; index < idArray.length(); index++)
{
AcDbObjectId id = idArray.at(index);

AcDbBlockReference* pBlockRef = NULL;
acdbOpenObject(pBlockRef, id, AcDb::kForRead);
if(pBlockRef->isErased() == Adesk::kTrue)
{
pBlockRef->close();
continue;
}

// Do some stuff with the block reference here.

pBlockRef->close();
}

return idArray.length();
}
Message 4 of 9
Anonymous
in reply to: cadMeUp

Replace some portions of your code with the following:

...

int cnt = 0;
for(int index = 0; index < idArray.length(); index++)
{
////AcDbObjectId id = idArray.at(index);

////AcDbBlockReference* pBlockRef = NULL;
////acdbOpenObject(pBlockRef, id, AcDb::kForRead);
////if(pBlockRef->isErased() == Adesk::kTrue)
////{
//// pBlockRef->close();
//// continue;
////}

AcDbObjectPointer pRef(idArray[index],
AcDb::kForRead);
if (pRef.openStatus() == Acad::eOk)
{
AcDbBlockTableRecordPointer pBtr(pRef->blockId(), AcDb::kForRead);
if (pBtr.openStatus() == Acad::eOk && pBtr->isLayout())
cnt++;
}

// Do some stuff with the block reference here.

////pBlockRef->close();
}

return cnt; //idArray.length();
}
Message 5 of 9
cadMeUp
in reply to: cadMeUp

Thanks Luis!

How would I get this to compile in VS .NET 2002? I am getting compile errors:

c:\Projects\ProjectARX2005\PipeNumbers_Blocks\PnmBlocks.cpp(1008): error C2955: 'AcDbObjectPointer' : use of class template requires template argument list

c:\Projects\ProjectARX2005\PipeNumbers_Blocks\PnmBlocks.cpp(1008): error C2514: 'AcDbObjectPointer' : class has no constructors
C:\Programs\ObjectARX2005\inc\dbobjptr.h(226) : see declaration of 'AcDbObjectPointer'

c:\Projects\ProjectARX2005\PipeNumbers_Blocks\PnmBlocks.cpp(1008): error C2262: 'pRef' : cannot be destroyed

I have never used these objects before!
Message 6 of 9
Anonymous
in reply to: cadMeUp

Your welcome;

Those are smart pointers... if you are not using the arx wizard, highlight
the name - right-click and select go to definition, it will tell you the
header name, just added that on the top of the file #include <....>

HTH


Thanks Luis!

How would I get this to compile in VS .NET 2002? I am getting compile
errors:

c:\Projects\ProjectARX2005\PipeNumbers_Blocks\PnmBlocks.cpp(1008): error
C2955: 'AcDbObjectPointer' : use of class template requires template
argument list

c:\Projects\ProjectARX2005\PipeNumbers_Blocks\PnmBlocks.cpp(1008): error
C2514: 'AcDbObjectPointer' : class has no constructors
C:\Programs\ObjectARX2005\inc\dbobjptr.h(226) : see declaration of
'AcDbObjectPointer'

c:\Projects\ProjectARX2005\PipeNumbers_Blocks\PnmBlocks.cpp(1008): error
C2262: 'pRef' : cannot be destroyed

I have never used these objects before!
Message 7 of 9
cadMeUp
in reply to: cadMeUp

Thanks for your help Luis. I am not having any luck with it.
I cannot get it to compile with the 'AcDbObjectPointer' object line.

Anyway, the blocks that I have to use this routine on have attributes and the attribute values would have to be different, but with my routine it is finding 2 of each of those blocks, in other words there is a duplicate of what you see on the screen but you don't see the duplicate.

Have you tried my sample that I gave you? I can't see in my code where it is wrong, seems like it should work or maybe a bug. If you get the same results with the code that I wrote?

Thanks Luis!

Larry
Message 8 of 9
Anonymous
in reply to: cadMeUp

Larry;

Yes I tested your code and was getting the same results, is strange that you
could not use smart pointers, but no problem, here is your routine using
normal calls... HTH. 🙂

int GetBlockObjectCount(const CString& name)
{
AcDbBlockTable* pBlockTab = NULL;
AcDbDatabase* pCurDB = acDocManager->curDocument()->database();
pCurDB->getBlockTable(pBlockTab, AcDb::kForRead);

AcDbBlockTableRecord* pTabRec = NULL;
if(pBlockTab->getAt(name, pTabRec, AcDb::kForRead) != Acad::eOk)
{
pBlockTab->close();
return -1;
}
pBlockTab->close();

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

AcDbObjectIdArray idArray;
pTabRec->getBlockReferenceIds(idArray);
pTabRec->close();

if(idArray.length() == 0)
return -1;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


int cnt = 0;
for(int index = 0; index < idArray.length(); index++)
{
AcDbObjectId id = idArray.at(index);
AcDbBlockReference *pRef = NULL;
AcDbBlockTableRecord *pBtr = NULL;
if ((acdbOpenObject(pRef, id, AcDb::kForRead) == Acad::eOk) &&
(acdbOpenObject(pBtr, pRef->blockId(), AcDb::kForRead) == Acad::eOk) &&
pBtr->isLayout())
{
cnt++;
pRef->close();
pBtr->close();
}

//if (pBlockRef == Acad::eOk && pBlockRef->isLayout())
// cnt++;
////if(pBlockRef->isErased() == Adesk::kTrue)
////{
//// pBlockRef->close();
//// continue;
////}

//AcDbObjectPointer pRef(idArray[index],
AcDb::kForRead);
//if (pRef.openStatus() == Acad::eOk)
//{
// AcDbBlockTableRecordPointer pBtr(pRef->blockId(), AcDb::kForRead);
// if (pBtr.openStatus() == Acad::eOk && pBtr->isLayout())
// cnt++;
//}

// Do some stuff with the block reference here.

////pBlockRef->close();
}

return cnt; //idArray.length();
}
Message 9 of 9
pkohut-og
in reply to: cadMeUp

When you paste the block into another drawing a temparary BTR is created and then erased. This is why you see 2 references. If you open the parent blockId (block table
record) you will see it has a temporary block name (or eWasErased if the last param was not true).
Saving and then opening the second drawing eliminates the
temporary block table record.

Paul Kohut

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

Post to forums  

Autodesk Design & Make Report

”Boost