Finding block references in external references

Finding block references in external references

Anonymous
Not applicable
2,282 Views
6 Replies
Message 1 of 7

Finding block references in external references

Anonymous
Not applicable

I wrote a function that takes a block name, external reference name and a vector of points. The function will look for the external reference and return all the positions of the specified blocks in that xRef. The code works in most cases but sometimes it returns an empty array when I call  xRefBlockTableRecord->getBlockReferenceIds( blockIds ) even though it has already found a block table record in the xRef. Is there someway that blocks are not accessible in the xRef? Or is there an error in my code? Thanks for any advice you can offer. The code is below.

 

bool getPoints( const ACHAR *xRefName, const ACHAR *moduleName, std::vector<AcGePoint2d> *points )
{
	Acad::ErrorStatus errorStatus;
	AcDbDatabase *database = acdbHostApplicationServices()->workingDatabase();
	AcDbBlockTable *blockTable = NULL;
	AcDbBlockTableRecord *blockTableRecord = NULL;
	AcDbDatabase *xRefDatabase = NULL;
	const ACHAR *xRefPath = NULL;
	AcDbDatabase *xRefDWGDatabase = NULL;
	AcDbBlockTable *xRefBlockTable = NULL;
	AcDbBlockTableRecord *xRefBlockTableRecord = NULL;
	AcDbEntity *ent = NULL;
	AcDbBlockReference *ref = NULL;
	AcDbObjectIdArray blockIds;
	AcDbObjectIdArray refIds;
	//xRef transformations
	double xOffset = 0;
	double yOffset = 0;
	double rotation = 0;

	//Get the block table for our database
	errorStatus = database->getBlockTable(blockTable, AcDb::kForRead);
	if( errorStatus != Acad::eOk )
	{
		acutPrintf(L"\nError getting block table %s", acadErrorStatusText( errorStatus ) );     
		return false;
	}

	//Get the block table record for the external reference
	errorStatus = blockTable->getAt( xRefName, blockTableRecord, AcDb::kForRead );
	if( errorStatus != Acad::eOk )
	{
		acutPrintf(L"\nError could not get xref %s %s", xRefName, acadErrorStatusText( errorStatus ) ); 
		blockTable->close();
		return false;
	}

	//Get the transformation of the xRef
	errorStatus = blockTableRecord->getBlockReferenceIds( refIds );
	if( errorStatus != Acad::eOk || refIds.length() < 1 )
	{
		acutPrintf(L"\nError could not get xref reference ids %s", acadErrorStatusText( errorStatus ));     
		blockTable->close();
		return false;
	}

	//Open the reference
	acdbOpenObject( ent, refIds.at(0), AcDb::kForRead );
	if( ent == NULL )
	{
		acutPrintf(L"\nError could not get xref reference entity %s", acadErrorStatusText( errorStatus ));     
		blockTable->close();
		return false;
	}
	//Cast the reference
	ref = AcDbBlockReference::cast( ent );
	if( ref == NULL )
	{
		acutPrintf(L"\nError could not get xref reference %s", acadErrorStatusText( errorStatus ));     
		blockTable->close();
		ent->close();
		return false;
	}
	
	//Get transformations
	xOffset = ref->position().x;
	yOffset = ref->position().y;
	rotation = ref->rotation();

	ent->close();

	xRefDatabase = blockTableRecord->xrefDatabase(true);
	blockTable->close();
	blockTableRecord->close();

	if( xRefDatabase == NULL )
	{
		acutPrintf(L"\nCould not get external reference database" );
		return false;
	}
	//Get path for external reference dwg file
	xRefPath = acdbOriginalXrefFullPathFor( xRefDatabase ); 
	if( xRefPath == NULL )
	{
		acutPrintf(L"\nCould not get external reference path" );
		return false;
	}
	
	//Get database for the external reference drawing
	xRefDWGDatabase = new AcDbDatabase(Adesk::kFalse);
	errorStatus = xRefDWGDatabase->readDwgFile(xRefPath);
	if( errorStatus != Acad::eOk )
	{
		acutPrintf(L"\nError could not read xref file %s", acadErrorStatusText( errorStatus ));   
		delete xRefDWGDatabase;
		return false;
	}
	//Get the block table for the open model reference file
	errorStatus = xRefDWGDatabase->getBlockTable( xRefBlockTable, AcDb::kForRead );
	if( errorStatus != Acad::eOk )
	{
		acutPrintf(L"\nError could not load xref block table %s", acadErrorStatusText( errorStatus ));
		delete xRefDWGDatabase;
		return false;
	}

	//Get the definition for the block in the the external reference
	errorStatus = xRefBlockTable->getAt( moduleName, xRefBlockTableRecord, AcDb::kForRead );
	if( errorStatus != Acad::eOk )
	{
		acutPrintf(L"\nError could not get xref block table record %s", acadErrorStatusText( errorStatus ));     
		xRefBlockTable->close();
		delete xRefDWGDatabase;
		return false;
	}
	
	xRefBlockTable->close();

	errorStatus = xRefBlockTableRecord->getBlockReferenceIds( blockIds );
	if( errorStatus != Acad::eOk )
	{
		acutPrintf(L"\nError could not get xref block ids %s", acadErrorStatusText( errorStatus ));     
		xRefBlockTableRecord->close();
		delete xRefDWGDatabase;
		return false;
	}


	//Push all points into the vector
	for( int i = 0; i < blockIds.length(); i++ )
	{
		ent = NULL;
		acdbOpenObject( ent, blockIds.at(i), AcDb::kForRead );
		if( ent != NULL )
		{
			ref = NULL;
			ref = AcDbBlockReference::cast( ent );
			if( ref != NULL )
			{
				AcGePoint2d pnt;
				pnt.x = ref->position().x;
				pnt.y = ref->position().y;

				//Transfrom point
				pnt.x += xOffset;
				pnt.y += yOffset;
				points->push_back( pnt );
			}
			ent->close();
		}		
	}
	delete xRefDWGDatabase;
	xRefBlockTableRecord->close();
	return true;
}
0 Likes
Accepted solutions (1)
2,283 Views
6 Replies
Replies (6)
Message 2 of 7

Alexander.Rivilis
Mentor
Mentor

Maybe it is dynamic block?

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

0 Likes
Message 3 of 7

Anonymous
Not applicable

How would I check for a dynamic block?

0 Likes
Message 4 of 7

Alexander.Rivilis
Mentor
Mentor
Accepted solution

Finding all block references of a dynamic block

(hope you can translate this code from C# to ObjectARX)

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 5 of 7

Anonymous
Not applicable

Ok that looks promising I will play around with it and post back if it works out.

0 Likes
Message 6 of 7

Anonymous
Not applicable

I have played around with some arx code and can now detect that there are "anonymous blocks" in the table usually labeled something like *U12 where the number will vary from block to block. Do you know where these anonymous blocks come from? in the article you linked they say "An anonymous block is created for each different state of the dynamic block" but I dont have any states in my blocks.

0 Likes
Message 7 of 7

Alexander.Rivilis
Mentor
Mentor

@Anonymous wrote:

...Do you know where these anonymous blocks come from? in the article you linked they say "An anonymous block is created for each different state of the dynamic block" but I dont have any states in my blocks...


If the dynamic block has parameters, then changing any of the parameters results in the creation of an anonymous block.

If you post a fragment of a dwg-file with such block, then I can explain in more detail. However, this does not apply to the main issue of this topic.

 

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

0 Likes