Author Topic: Nested copy  (Read 10344 times)

0 Members and 1 Guest are viewing this topic.

LE

  • Guest
Nested copy
« on: March 22, 2006, 05:20:56 PM »
Here is the first code, I came up to copy a nested object:

Code: [Select]
inline AcDbDatabase*
CURDB() { return acdbHostApplicationServices()->workingDatabase(); }

Code: [Select]
static void LESQsomefunctions_CNEST(void)
{

const char * str;
str = "\nSelect nested entity: ";
ads_name entres;
ads_point ptres;
int pickflag = 0;
ads_matrix xformres;
resbuf* containers;
AcDbObjectId objId;

if (acedNEntSelP(str, entres, ptres, pickflag, xformres, &containers) == RTNORM) {
acutRelRb(containers);

if (acdbGetObjectId(objId, entres) != Acad::eOk) return;
AcDbObjectPointer<AcDbEntity> pEntity(objId, AcDb::kForRead);
if (pEntity.openStatus() == Acad::eOk) {

const char *pCname = pEntity->isA()->name();
acutPrintf("\nNAME %s", pCname); // for debug only
AcGeMatrix3d xform;
AcDbEntity *pEnt = NULL;
if (pEntity->getTransformedCopy(xform, pEnt) == Acad::eOk) {
acutPrintf("\nNest OK. . ."); // for debug only

AcDbObjectId curSpaceId=CURDB()->currentSpaceId();
AcDbBlockTableRecordPointer pBlockTableRecord(curSpaceId, AcDb::kForWrite);

if (pBlockTableRecord.openStatus() == Acad::eOk) {
pBlockTableRecord->appendAcDbEntity(pEnt);

pEnt->transformBy(xform); //<<<<?

pEnt->close();
}//end of if openStatus
}//end of getTransformedCopy
}//end of if openStatus
}else {
acutRelRb(containers);
}
}//end of command CNEST

Am I in the right track?... the object(s) are copied, but I think I need to do some more steps...

Thanks!

Alexander Rivilis

  • Bull Frog
  • Posts: 212
  • Programmer from Kyiv (Ukraine)
Re: Nested copy
« Reply #1 on: March 23, 2006, 04:03:35 AM »
Hi, Luise!
1) If entity is complex (AcDb2dPolyline, AcDb3dPolyline, etc.) you need to do deepClone()
2) You must to initialize xform matrix. It is not easy. You need recursivle find all owner block table records
and get pBTR->origion() and pRef->blockTransform():
Code: [Select]
AcGeMatrix3d xform = pRef->blockTransform(); // pRef - is AcDbBlockReference
AcGePoint3d pt3dBlkOrigin = pBTR->origin(); // pBTR - is AcDbBlockTableRecord for this AcDbBlockReference
if (pt3dBlkOrigin != AcGePoint3d::kOrigin) {
    AcGeVector3d xformOrigin = xform.translation();
    AcGeVector3d vectorOrigin(pt3dBlkOrigin.x,pt3dBlkOrigin.y,pt3dBlkOrigin.x);
    vectorOrigin.transformBy(xform);
    xformOrigin -= vectorOrigin;
    xform.setTranslation(xformOrigin);
}
« Last Edit: March 23, 2006, 04:12:50 AM by Rivilis »

LE

  • Guest
Re: Nested copy
« Reply #2 on: March 23, 2006, 05:17:32 PM »
Hi Alexander;

I went the deepCloneObjects() route... at least AutoCAD does not crash... I am using a selection set and acedSSNameX(), but it is kind of hard to get the AcDbBlockReference from the resbuf... to get the matrix data from blockTransform() . . . and being able to use the transformBy() for each of the nested objects selected

The cloned works without the transformation....

For now, I am leaving the function for a while....

Thanks.

Alexander Rivilis

  • Bull Frog
  • Posts: 212
  • Programmer from Kyiv (Ukraine)
Re: Nested copy
« Reply #3 on: March 23, 2006, 05:28:22 PM »
... at least AutoCAD does not crash...
:-) It's a good news!
The cloned works without the transformation....
It is simplest way to make a copy of complex entity.

LE

  • Guest
Re: Nested copy
« Reply #4 on: March 23, 2006, 05:40:54 PM »
Thank you Alexander.

Well... I think some code will say more, please have a look of what I'm doing [some portions of the code are part of the sample projects from the SDK]:

Code: [Select]
    ads_name ss;
    if (RTNORM != acedSSGet( ":N", NULL, NULL, NULL, ss ))
    {
        acutPrintf( "acedSSGet cancelled\n" );
        return;
    }

    long length;
    if (RTNORM != acedSSLength( ss, &length ) || 0 == length)
    {
        acutPrintf( "empty selection set\n" );
        acedSSFree( ss );
        return;
    }

    ads_name          ent;
    AcDbObjectId      id, objId1, objId2;
    AcDbObjectIdArray list;
    AcDbIdMapping     pIdMap;

struct resbuf *pRb;

for (long i = 0; i < length; i++) {
        if (RTNORM != acedSSNameX(&pRb, ss, i)) return;
            continue;

   struct resbuf *pTemp;

    int i;
    for (i=1, pTemp = pRb;i<3;i++, pTemp = pTemp->rbnext)
        { ; }
    ads_name ename;
    ads_name_set(pTemp->resval.rlname, ename);

        if (Acad::eOk != acdbGetObjectId( id, ename )) return;
            continue;

        list.append( id );
    }
    acedSSFree( ss );
   AcDbObjectId blockId = getBlockId( ACDB_MODEL_SPACE );
    if (blockId != 0) {
        if (Acad::eOk != acdbHostApplicationServices()->workingDatabase()
            ->deepCloneObjects( list, blockId, pIdMap ))
            acutPrintf( "Error on deepCloneObjects\n" );
    }
    else
        acutPrintf( "Error in getting ModelSpace ID\n" );

As you can see, how can I get the block reference from the pRb resbuf ?

Thanks!

LE

  • Guest
Re: Nested copy
« Reply #5 on: March 23, 2006, 05:55:58 PM »
I was going to look into the resbuf and do something like this:

Were prevrb is the bufer taking from pRb
Code: [Select]
if (acdbGetObjectId(objId1, prevrb->resval.rlname) != Acad::eOk) return;

AcDbObjectPointer<AcDbEntity> pInsert(objId1,AcDb::kForRead);

if (pInsert.openStatus() == Acad::eOk) {
AcDbBlockReference *pBlock = AcDbBlockReference::cast(pInsert.object());

AcGeMatrix3d mat = pBlock->blockTransform();
}

Then apply that matrix data into the nested object... I know sound easy.. but it is not... he he

Code: [Select]
pEnt->transformBy(mat);

 :-(

LE

  • Guest
Re: Nested copy
« Reply #6 on: March 23, 2006, 06:21:38 PM »
Had anyone being able to use getTransformedCopy() and have the nested copy to work?....

For example the following function works, but... crashes AutoCAD.... what do I have to use in order to make it work?

Note: Test the code in a start from scratch drawing [because is going to crash AutoCAD].... draw some lwpolylines and lines, circles - convert them into a block and then call the command CNEST..., it will work for a while

Code: [Select]
static void LESQsomefunctions_CNEST(void)
{

const char * str;
str = "\nSelect nested entity: ";
ads_name entres;
ads_point ptres;
int pickflag = 0;
ads_matrix xformres;
resbuf *containers, *rb, *prevrb;
AcDbObjectId objId, objId1;

if (acedNEntSelP(str, entres, ptres, pickflag, xformres, &containers) == RTNORM) {

rb = containers;
while (rb != NULL) {
prevrb = rb;
rb = containers->rbnext;
}

      if (acdbGetObjectId(objId1, prevrb->resval.rlname) != Acad::eOk) return;

  acutRelRb(rb);
  acutRelRb(containers);
  acutRelRb(prevrb);

  if (acdbGetObjectId(objId, entres) != Acad::eOk) return;

  AcDbObjectPointer<AcDbEntity> pEntity(objId, AcDb::kForRead);
  AcDbObjectPointer<AcDbEntity> pInsert(objId1,AcDb::kForRead);

  if (pEntity.openStatus() == Acad::eOk && pInsert.openStatus() == Acad::eOk) {

const char *pCname = pEntity->isA()->name();
acutPrintf("\nNest object is: %s", pCname);

const char *pCname1 = pInsert->isA()->name();
acutPrintf("\nTop object is: %s", pCname1);

AcDbBlockReference *pBlock = AcDbBlockReference::cast(pInsert.object());

AcGeMatrix3d mat = pBlock->blockTransform();

AcGeMatrix3d xform;
AcDbEntity *pEnt = NULL;

if (pEntity->getTransformedCopy(xform, pEnt) == Acad::eOk) {
acutPrintf("\nNest OK. . .");

AcDbObjectId curSpaceId=CURDB()->currentSpaceId();
AcDbBlockTableRecordPointer pBlockTableRecord(curSpaceId, AcDb::kForWrite);

if (pBlockTableRecord.openStatus() == Acad::eOk) {
pBlockTableRecord->appendAcDbEntity(pEnt);

pEnt->transformBy(mat);
pEnt->close();

}//end of if openStatus
}//end of getTransformedCopy
}//end of if openStatus
}else { 
acutRelRb(rb);
acutRelRb(containers);
acutRelRb(prevrb);
}
}//end of command CNEST

How about the other swamper's any of you, had tried any alternative to clone objects in ObjectARX ?

Thanks!

MickD

  • Gator
  • Posts: 3310
  • (x-in)->[process]->(y-out)
Re: Nested copy
« Reply #7 on: March 23, 2006, 10:00:02 PM »
would -

rb = containers;
   while (rb != NULL) {
       prevrb = rb;
       rb = containers->rbnext;

be better written as -

rb = containers;
   while (rb != NULL) {
       prevrb = rb;
       rb = rb->rbnext;

??

hth
Forth is like the Tao: it is a Way, and is realized when followed.
Its fragility is its strength; its simplicity is its direction - Michael Ham

Lao Tzu: “To attain knowledge, add things
every day; to obtain wisdom, remove things every day.”

MickD

  • Gator
  • Posts: 3310
  • (x-in)->[process]->(y-out)
Re: Nested copy
« Reply #8 on: March 23, 2006, 10:06:40 PM »
scrap that, I thought about it a bit harder :ugly:
Forth is like the Tao: it is a Way, and is realized when followed.
Its fragility is its strength; its simplicity is its direction - Michael Ham

Lao Tzu: “To attain knowledge, add things
every day; to obtain wisdom, remove things every day.”

MickD

  • Gator
  • Posts: 3310
  • (x-in)->[process]->(y-out)
Re: Nested copy
« Reply #9 on: March 23, 2006, 11:56:31 PM »
Luis, what happens if you select an item that isn't part of the block reference??
i.e. if you select one of the new entities you added to the db in the last run of the command ;)
Forth is like the Tao: it is a Way, and is realized when followed.
Its fragility is its strength; its simplicity is its direction - Michael Ham

Lao Tzu: “To attain knowledge, add things
every day; to obtain wisdom, remove things every day.”

LE

  • Guest
Re: Nested copy
« Reply #10 on: March 23, 2006, 11:57:34 PM »
Thank you Mick;

I been working on this, all day and still have not being able to come up with a solution, as normal/always most of the samples codes [if any/or some] do not apply or are not well explained...

As I said, the last function works, the problem is the crashing, appears to be the objectID's... something I have not done or being involved to much... man.   :oops:

LE

  • Guest
Re: Nested copy
« Reply #11 on: March 23, 2006, 11:58:18 PM »
with any of the two functions?

LE

  • Guest
Re: Nested copy
« Reply #12 on: March 24, 2006, 12:04:18 AM »
Crash....

LE

  • Guest
Re: Nested copy
« Reply #13 on: March 24, 2006, 12:09:57 AM »
The function that I did using deepCloneObjects() works without the crash... with new and existing objects...

I need on that one, how to get the INSERT from the resbuf....  :oops:

MickD

  • Gator
  • Posts: 3310
  • (x-in)->[process]->(y-out)
Re: Nested copy
« Reply #14 on: March 24, 2006, 12:14:28 AM »
If you pick a line that you created in the command (as they are most likely hidden on/under your block because that's where you xformed it to)  or any line for that matter, you can't have a pointer to a block reference.
keep moving your block around before you run the command and it will be fine, if you don't you 'may' pick just a single ent and not a block insert which will cause it to crash.
IOW, check the selected item is a block insert before doing your mojo ;)
Forth is like the Tao: it is a Way, and is realized when followed.
Its fragility is its strength; its simplicity is its direction - Michael Ham

Lao Tzu: “To attain knowledge, add things
every day; to obtain wisdom, remove things every day.”