Data shortcut to custom objects

Data shortcut to custom objects

olivier.berrier
Contributor Contributor
420 Views
2 Replies
Message 1 of 3

Data shortcut to custom objects

olivier.berrier
Contributor
Contributor

Hi
i created some custom objects (ARX & DBX). Some objects can use a large amount of memory.
I would like to create a simple "data shortcut" (like Civil 3D) :
1) so I create the object in one drawing,
2) and get a reference to that object in a second drawing (display, execute commands...)

I am familiar with wblockCloneObjects but I don't know if I can use it in the DBX.
Should I call it in dwgInFields to 'fill' the object in the second drawing ?
Any advice would be appreciated.
Thanks

Olivier BERRIER
www.geo-media.com
0 Likes
421 Views
2 Replies
Replies (2)
Message 2 of 3

mediaengineerDE
Contributor
Contributor

Hello Olivier,

 

I would do it as follows, if I understood correctly what you want to try to accomplish.

 

1) Save in the second drawing only the filepath, filename and handle (AcDbHandle, not ObjectId!) of the object you want to reference from the first drawing. The filepath and filename can be optional, if you have this saved at some other place.  You can get the handle with

    AcDbObjectId oId = AcDbObjectId::kNull;
    AcDbHandle handle = oId.handle();

You may save (infile, outfile) the handle as an AcString in your second drawing. Convert the handle to AcString with:

	AcDbHandle		thisHandle;
	pEnt->getAcDbHandle(thisHandle);
	TCHAR  handbuffer[17];
	thisHandle.getIntoAsciiBuffer(handbuffer);
	AcString astrHandle = handbuffer;

 

2) When you need to access the data of the first drawing from the second drawing, read the first dwg file with

AcString filePathAndName = T("some_path\drawing1.dwg");
AcDbDatabase *pDb = new AcDbDatabase(Adesk::kFalse, true);
pDb->readDwgFile(filePathAndName.kACharPtr(), AcDbDatabase::OpenMode::kForReadAndAllShare)

You can skip this if you have both databases already open.

 

3) You may consider to close the input when reading the file:

	//If a drawing file is associated with this database, then this function forces an
	//immediate read of all necessary information from the file into the database object.
	//If bCloseFile is true, the drawing file will be closed when it has been fully read into the AcDbDatabase.
	if (Acad::eOk != (asErr = pDb->closeInput(true)))
	{
		acutPrintf(LFF LIT("Failed to closeInput for %s!"), ASF, astrDbFileName->kACharPtr());
	}

 

4) To get the ObjectId of the object you want to access in the opened database, use this:

Acad::ErrorStatus AuStUtilDb::handleStrToObjId(AcDbDatabase* db, LPCTSTR handleStr, AcDbObjectId& objId, bool speak)
{
    ASSERT(handleStr != nullptr);
	ASSERT(db != nullptr);

    AcDbHandle objHandle(handleStr);
    Acad::ErrorStatus es;

    es = db->getAcDbObjectId(objId, false, objHandle);
    if (es != Acad::eOk) {
        if (speak) {
            acutPrintf(LIT("\nERROR: Could not translate handle to objectId (%s)"), AuStUtilUi::rxErrorStr(es));
        }
        return Acad::eInvalidInput;
    }
    else
        return Acad::eOk;
}

 

5) Change the database context with

 

acdbHostApplicationServices()->setWorkingDatabase(pDb);

 

to access the first database (drawing) you read in 2).

 

6) Get your object with a smart object pointer, you need to know only the ObjectId that we got in 4).

AcDbSmartObjectPointer<YouAcDbObjectDerivedClass> pObj(oId, AcDb::kForRead);

 

7) Now you can access the data from your object from the drawing.

 

😎 Remember to change the database context back to your first drawing when you are done!

acdbHostApplicationServices()->setWorkingDatabase(pFirstDrawing);

 

9) Do not forget to delete the memory allocated for the database in step 2) (if applicable).

 

Hope this helps!

Cheers,

Jens

 

 

 

 

0 Likes
Message 3 of 3

olivier.berrier
Contributor
Contributor

Thank you Jens for this very precise answer. You give great tips.
I get the overall point. I will try to implement it in the AcRx::kLoadDwgMsg :
- check if the current drawing contains references to another drawing.
- for each reference, create a custom object
- access to the custom object in the source drawing (as you described)
- copy the data from 'source object' to 'new object' (I think 'copyFrom' will do the job).
- add the new object to the current drawing.

 

I'll let you know the results of that test.

Best regards.

Olivier BERRIER
www.geo-media.com
0 Likes