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

Finding block positions in an external reference

10 REPLIES 10
SOLVED
Reply
Message 1 of 11
jmaniaAZNPL
987 Views, 10 Replies

Finding block positions in an external reference

I have written some code to grab block references from an external references dwg file. I can get the references fine but when i draw the positions of the blocks they are all slightly off. See the pictures below.

 

POSTREF1.png

 

The white Xs mark where the position is being calculated in my code. You can see that they are pushed over to right and rotated.

 

POSTREF2.png

 

This picture shows the blocks open in the external reference where they have positions located at the center of each block. Below is the code I am using to draw the Xs.

	std::vector<AcDbEntity*> points;
	getObjects( L"xModel", L"_MODULE POINT", &points );
	for( int i = 0; i < points.size(); i++ )
	{
			
		AcDbBlockReference *ref = NULL;
		ref = AcDbBlockReference::cast( points.at(i) );

		if( ref != NULL )
		{
			modulePoint[0] = ref->position().x;
			modulePoint[1] = ref->position().y;
			modulePoint[2] = 0;
			//acedTrans( modulePoint, &wcs, &ucs, FALSE, modulePoint );
			createLine( modulePoint[0]-2, modulePoint[1], modulePoint[0]+2, modulePoint[1], L"0" );
			createLine( modulePoint[0], modulePoint[1]-2, modulePoint[0], modulePoint[1]+2, L"0" );

		}

		points.at(i)->close();
	}

 

I have attempted to translate the points from wcs to ucs but that does not seem to help.

 

 

 

10 REPLIES 10
Message 2 of 11

You must consider AcDbBlockReference::blockTransform transormation for xref.

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | 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 3 of 11

Thank you for the answer. I have tried that and I get the points far out in space shown in the following. Am I missing something else that I have to do?

POSTREF3.png

 

The updated code.

	std::vector<AcDbEntity*> points;
	getObjects( L"xModel", L"_MODULE POINT", &points );
	for( int i = 0; i < points.size(); i++ )
	{
			
		AcDbBlockReference *ref = NULL;
		ref = AcDbBlockReference::cast( points.at(i) );

		if( ref != NULL )
		{
			AcGeMatrix3d trans = ref->blockTransform();
			AcGeVector3d pnt;
			pnt.x = ref->position().x;
			pnt.y = ref->position().y;
			pnt.z = 0;

			pnt.transformBy( trans.inverse() );
			

			modulePoint[0] = pnt.x;
			modulePoint[1] = pnt.y;
			modulePoint[2] = 0;

			//acedTrans( modulePoint, &wcs, &ucs, FALSE, modulePoint );
			createLine( modulePoint[0]-2, modulePoint[1], modulePoint[0]+2, modulePoint[1], L"0" );
			createLine( modulePoint[0], modulePoint[1]-2, modulePoint[0], modulePoint[1]+2, L"0" );
		}

		points.at(i)->close();
	}
Message 4 of 11

blockTransform() not for AcDbBlockReference in external reference but for AcDbBlockReference of external reference attached to current drawing.

Also you have to consider position of AcDbBlockReference of external reference.

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | 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 11

Thanks for the clarification Alexander you are always so helpful. I am trying to figure out how to get the AcDBlockReference of the external reference but I am having some trouble as I only grab the BlockRecord for the DWG file in my code. Maybe I am misunderstanding some of the workings of external references in ARX as I am very new to it.  Below is the function I am using to get the blocks from the external references I was hoping you could take a look if you have some time. Thank you in advanced.

 

bool getObjects( ACHAR *xRefName, ACHAR *layer, std::vector<AcDbEntity*> *objects, AcGeMatrix3d *transform )
{
	Acad::ErrorStatus errorStatus;
	AcDbDatabase *database = acdbHostApplicationServices()->workingDatabase();
	AcDbBlockTable *blockTable = NULL;
	AcDbBlockTableRecord *modelBlockTableRecord = NULL;
	AcDbBlockTableRecord *blockTableRecord = NULL;
	AcDbDatabase *xRefDatabase = NULL;
	const ACHAR *xRefPath = NULL;
	AcDbDatabase *xRefDWGDatabase = NULL;
	AcDbBlockTable *xRefBlockTable = NULL;
	AcDbBlockTableRecord *xRefBlockTableRecord = NULL;

	//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 table record in model space
	errorStatus = blockTable->getAt(ACDB_MODEL_SPACE,modelBlockTableRecord,AcDb::kForRead); 
	if( errorStatus != Acad::eOk )
	{
		acutPrintf(L"\nError getting model space block table record %s", acadErrorStatusText( errorStatus ) );     
		blockTable->close();
		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 ) ); 
		modelBlockTableRecord->close();
		blockTable->close();
		return false;
	}

	xRefDatabase = blockTableRecord->xrefDatabase(true);

	if( xRefDatabase == NULL )
	{
		acutPrintf(L"\nCould not get external reference database" );
		modelBlockTableRecord->close();
		blockTable->close();
		blockTableRecord->close();
		return false;
	}
	//Get path for external reference dwg file
	xRefPath = acdbOriginalXrefFullPathFor( xRefDatabase ); 
	if( xRefDatabase == NULL )
	{
		acutPrintf(L"\nCould not get external reference path" );
		modelBlockTableRecord->close();
		blockTable->close();
		blockTableRecord->close();
		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 ));     
		modelBlockTableRecord->close();
		blockTable->close();
		blockTableRecord->close();
		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 ));     
		modelBlockTableRecord->close();
		blockTable->close();
		blockTableRecord->close();
		return false;
	}

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

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

	for( int i = 0; i < blockIds.length(); i++ )
	{
		AcDbEntity *ent = NULL;
		acdbOpenObject( ent, blockIds.at(i), AcDb::kForRead );
		if( ent != NULL )
		{
			objects->push_back( ent );
		}		
	}

	modelBlockTableRecord->close();
	blockTable->close();
	blockTableRecord->close();
	xRefBlockTable->close();
	xRefBlockTableRecord->close();
	return true;
}
Message 6 of 11

One Xref can be attaching many times in different positions, different rotations, different scales. Information of position/rotation/scales is in AcDbBlockReference's which refer to AcDbBlockTableRecord  of xref. So you can not get information about position of entities into Xref if you have only name of Xref but have not information of Xref position/rotation/scale (e.g. AcDbBlockReference of Xref).

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | 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 7 of 11

@jmaniaAZNPL

 

Hope this video help you understand what wrong in your algorithm:

 

 

 

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | 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 8 of 11

Thank you so much. I grabbed the first reference to the xref and got the translation.

Message 9 of 11
bjevtic
in reply to: Alexander.Rivilis

Dear Alex,

 

I notice you have not only ArxDbg (very useful tool) in right-click shortcut, but also MgdDbg.

 

If you don't mind me asking, what is MgdDbg and what is it used for?

Have fun
Message 10 of 11
Alexander.Rivilis
in reply to: bjevtic


@bjevtic wrote:

Dear Alex,

 

I notice you have not only ArxDbg (very useful tool) in right-click shortcut, but also MgdDbg.

 

If you don't mind me asking, what is MgdDbg and what is it used for?


MgdDbg is a analog of ARXDBG created with help of AutoCAD .NET API. Sometimes it is more convenient than ARXDBG.

https://github.com/ADN-DevTech/MgdDbg

 

There is a ready to use bundle of MGDDBG for AutoCAD versions up to 2018: http://adn-cis.org/assets/gallery/AutoCAD/MgdDbg.zip

 

 

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | 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 11 of 11
bjevtic
in reply to: Alexander.Rivilis

Thanks

Have fun

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

Post to forums  

Autodesk Design & Make Report

”Boost