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.
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.
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.
Solved! Go to Solution.
Solved by Alexander.Rivilis. Go to Solution.
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
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?
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(); }
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
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; }
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
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
Thank you so much. I grabbed the first reference to the xref and got the translation.
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?
@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