Author Topic: Insert Drawing with acedDragGen() ?  (Read 5791 times)

0 Members and 1 Guest are viewing this topic.

LE

  • Guest
Insert Drawing with acedDragGen() ?
« on: July 19, 2006, 07:20:08 PM »
Hi;

I'm doing an exercise about a MFC dialog for drawing preview and insertions, here are some portions of my code (later I will include most or the whole C++ solution - if needed)

Now, I think I did all the basics, but have not been able to accomplish the drag view.... Can someone have a look or maybe knows how to implement this...

Thanks.

The function insertDWG().... need more touch-ups.... [and to keep this forum alive!]

Code: [Select]
void ident_init(ads_matrix iD)
{
int i, j;
for (i=0; i<=3; i++)
for (j=0; j<=3; j++)
iD[i][j] = 0.0;
for (i=0; i<=3; i++)
iD[i][i] = 1.0;
}

int scnf(ads_point pt, ads_matrix mt);

int dragsample(ads_point usrpt, ads_matrix matrix);

int dragsample(ads_point usrpt, ads_matrix matrix)
{
ident_init(matrix); // Initialize to identity.
// Initialize translation vector.
matrix[0][T] = usrpt[X];
matrix[1][T] = usrpt[Y];
matrix[2][T] = usrpt[Z];

return RTNORM; // Matrix was modified.
}

static void insertDWG (CString sFileName,CString baseName,ads_point pt)
{
Acad::ErrorStatus es;
AcDbDatabase *pNewDb = new AcDbDatabase(Adesk::kFalse);
acDocManager->lockDocument(acDocManager->curDocument());
es = pNewDb->readDwgFile(sFileName,_SH_DENYNO,false);
if (es != Acad::eOk)
{
acutPrintf("\nError on reading file= %s",acadErrorStatusText(es));
return;
}

AcDbDatabase *pDb;
pDb = acdbHostApplicationServices()->workingDatabase();
//pDb->insert(AcGeMatrix3d::kIdentity,pNewDb);
baseName.MakeUpper();
char * pch;
pch = strstr(baseName,".DWG");
strncpy(pch,"",3);
AcDbObjectId blockId;
if((es = pDb->insert(blockId,baseName,pNewDb)) == Acad::eOk)
{
AcDbObjectId curSpaceId = pDb->currentSpaceId();
AcDbBlockReference *pBlockReference = new AcDbBlockReference;
pBlockReference->setBlockTableRecord(blockId);
AcDbObjectId pOutputId;
AcDbBlockTableRecord *pBlockTableRecord = NULL;
if (acdbOpenObject(pBlockTableRecord,curSpaceId,AcDb::kForWrite) == Acad::eOk)
{
pBlockTableRecord->appendAcDbEntity(pOutputId,pBlockReference);
pBlockTableRecord->close();
pBlockReference->setPosition(AcGePoint3d(pt[X],pt[Y],pt[Z]));

//pBlockReference->setPosition(AcGePoint3d(0,0,0));

ads_name ename;
if (acdbGetAdsName(ename,pBlockReference->objectId()) == Acad::eOk)
{
int rc;
ads_name ssname;
ads_point return_pt, usrpt;
acedSSAdd(ename,ssname,ssname);

AcGePoint3d insPt = pBlockReference->position();
usrpt[0] = insPt.x;
usrpt[1] = insPt.y;
usrpt[2] = insPt.z;

ads_matrix matrix;
rc = acedDragGen(ssname,
"Drag selected objects", // Prompt 
0, // Display normal cursor (crosshairs)
dragsample, // Transformation function 
return_pt); // Set to the specified location.
}

pBlockReference->close();
//delete pNewDb;
}
}
else
{
acutPrintf("\nError on insertion= %s",sFileName,acadErrorStatusText(es));
delete pNewDb;
return;
}
}

void DPREVIEW::OnBnClickedOk()
{
CAcUiDialog::OnOK();
ads_point pt;
CString szDwg, baseName;
if (GetDialogData("CPREVIEW", szDwg) && !szDwg.IsEmpty() &&
GetDialogData("CPREVIEWBASENAME", baseName) && !szDwg.IsEmpty() &&
RTNORM == acedGetPoint(NULL, "\nSelect insertion point: ", pt))
{
insertDWG(szDwg, baseName, pt);
}
}
« Last Edit: July 20, 2006, 10:59:27 AM by LE »

MickD

  • Gator
  • Posts: 3314
  • (x-in)->[process]->(y-out)
Re: Insert Drawing with acedDragGen() ?
« Reply #1 on: July 19, 2006, 08:39:53 PM »
Do you really need this Luis?

strncpy(pch,"",3);

That say's to me that you're copying three null char's to the end of your block name after taking off the .dwg in the previous lines?
Otherwise with a brief look I can't see anything missing.
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: 3314
  • (x-in)->[process]->(y-out)
Re: Insert Drawing with acedDragGen() ?
« Reply #2 on: July 19, 2006, 08:48:53 PM »
But, I did notice there is no PreserveSourceDatabase = true in your pDb->insert()
I'd also try using the other 2 insert variations, are you getting any graphics at all?
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: Insert Drawing with acedDragGen() ?
« Reply #3 on: July 19, 2006, 09:41:58 PM »
Do you really need this Luis?

strncpy(pch,"",3);

That say's to me that you're copying three null char's to the end of your block name after taking off the .dwg in the previous lines?
Otherwise with a brief look I can't see anything missing.


I thought I needed to replace the four characters with the empty one.... first time using that function...  :-)

LE

  • Guest
Re: Insert Drawing with acedDragGen() ?
« Reply #4 on: July 19, 2006, 09:44:24 PM »
But, I did notice there is no PreserveSourceDatabase = true in your pDb->insert()
I'd also try using the other 2 insert variations, are you getting any graphics at all?

The command is working just fine, I want to implement a dragging ability...

I left the PreserveSourceDatabase default value....

LE

  • Guest
Re: Insert Drawing with acedDragGen() ?
« Reply #5 on: July 19, 2006, 09:56:11 PM »
I don't need the line below no?... (and I supposed that if it is used, needs to be use in pairs no? lock/unlock)

Quote
acDocManager->lockDocument(acDocManager->curDocument());

About to open my IDE.....

LE

  • Guest
Re: Insert Drawing with acedDragGen() ?
« Reply #6 on: July 19, 2006, 10:07:52 PM »
Do you really need this Luis?

strncpy(pch,"",3);

That say's to me that you're copying three null char's to the end of your block name after taking off the .dwg in the previous lines?
Otherwise with a brief look I can't see anything missing.


I thought I needed to replace the four characters with the empty one.... first time using that function...  :-)

I use this place as reference (a lot)

http://www.cplusplus.com/ref/cstring/strstr.html

It has a short sample implementation.

Draftek

  • Water Moccasin
  • Posts: 1501
Re: Insert Drawing with acedDragGen() ?
« Reply #7 on: July 20, 2006, 07:56:05 AM »
Luis - Have you looked at implementing the AcEdJig class?

There's quite a bit of code involved but you will have access to dragging, rotating, scaling, etc.

The SDK has a good example of how to use it. You'll have to obtain your insertion point inside the called method instead of before.
Soli Deo Gloria

Bobby C. Jones

  • Swamp Rat
  • Posts: 514
  • Cry havoc and let loose the dogs of war.
Re: Insert Drawing with acedDragGen() ?
« Reply #8 on: July 20, 2006, 10:35:03 AM »
Hey Luis,
Have you zoomed out while running this command?  Your dragsample is transforming the selection set from 0,0,0 to the current location of the cursor and the jig may just be off the screen.  I did the exact same thing recently and couldn't see the dragging entities until I zoomed out.  I reworked the matrix to transform the ss from a user selected basepoint instead of 0,0,0.

Here's my "dragsample" function, sorry for the .NET code.  m_basePoint is the user selected point.
Code: [Select]
    public SamplerStatus FollowCursor(Point3d currentPoint, ref Matrix3d transMat)
    {
      transMat = Matrix3d.Displacement(m_basePoint.GetVectorTo(currentPoint));

      return SamplerStatus.OK;
    }
Bobby C. Jones

LE

  • Guest
Re: Insert Drawing with acedDragGen() ?
« Reply #9 on: July 20, 2006, 11:55:04 AM »
Thank you Bobby;

Yes it was the matrix definition.... but I also found an excellent sample by the Master Александр Ривилис (Alexander Rivilis)

Code: [Select]
static ads_point Base;
static ads_matrix CMT;
static int DragFunction(ads_point pt, ads_matrix mat)
{
ads_point tp;
int axis;
AcGeVector3d v = asPnt3d(pt) — asPnt3d(Base);
AcGeMatrix3d gMat; gMat.setToTranslation(v);
memcpy(mat, gMat.entry, sizeof(ads_matrix));
memcpy(CMT, mat, sizeof(ads_matrix));
return RTNORM;
}

static void DragSamplerDragSampler(void)
{
ads_name ss;   ads_point p;
ads_getpoint(NULL, "\nFrom base point: ", Base);
if (acedSSGet(NULL,NULL,NULL,NULL,ss) == RTNORM) {
memcpy(CMT, AcGeMatrix3d::kIdentity.entry, sizeof(ads_matrix));
if (acedDragGen(ss,"\nTo here: ",0,DragFunction,p) == RTNORM) {
acedXformSS(ss,CMT);
}
}
}

PS. no problem about providing a .NET sample  :-)


LE

  • Guest
Re: Insert Drawing with acedDragGen() ?
« Reply #10 on: July 20, 2006, 01:57:39 PM »
For anyone interested here is the function, now working... still requires some minor details but, the basic is all in there.

And many thanks to Alexander Rivilis.... ! - for the matrix and acedDragGen sample.

Code: [Select]
// 1:23 PM 7/20/2006 - LE

static void insertDWG (CString sFileName, CString baseName, ads_point Base)
{
Acad::ErrorStatus es;
AcDbDatabase *pNewDb = new AcDbDatabase(Adesk::kFalse);
es = acDocManager->lockDocument(acDocManager->curDocument());
if (es != Acad::eOk) return;
es = pNewDb->readDwgFile(sFileName, _SH_DENYNO, false);
if (es != Acad::eOk)
{
acutPrintf("\nError on reading file= %s", acadErrorStatusText(es));
return;
}
AcDbDatabase *pDb;
pDb = acdbHostApplicationServices()->workingDatabase();
//pDb->insert(AcGeMatrix3d::kIdentity,pNewDb);
baseName.MakeUpper();
char * pch;
pch = strstr(baseName, ".DWG");
strncpy(pch, "", 3);
AcDbObjectId blockId;
if((es = pDb->insert(blockId, baseName, pNewDb)) == Acad::eOk)
{
AcDbObjectId curSpaceId = pDb->currentSpaceId();
AcDbBlockReference *pBlockReference = new AcDbBlockReference;
pBlockReference->setBlockTableRecord(blockId);
AcDbObjectId pOutputId;
AcDbBlockTableRecord *pBlockTableRecord = NULL;
if (acdbOpenObject(pBlockTableRecord, curSpaceId, AcDb::kForWrite) == Acad::eOk)
{
pBlockTableRecord->appendAcDbEntity(pOutputId, pBlockReference);
pBlockTableRecord->close();
pBlockReference->setPosition(AcGePoint3d(Base[X], Base[Y], Base[Z]));
pBlockReference->close();
}
actrTransactionManager->flushGraphics();
acedUpdateDisplay();
AcDbBlockReference *pRef = NULL;
if (acdbOpenAcDbObject((AcDbObject *&)pRef, pOutputId, AcDb::kForWrite) == Acad::eOk)
{
AcGePoint3d ins = pRef->position();
Base[X] = ins.x;
Base[Y] = ins.y;
Base[Z] = ins.z;
ads_name ename;
ads_name ss;
acedSSAdd(NULL, NULL, ss);
es = acdbGetAdsName(ename, pOutputId);
if (es == Acad::eOk)
{
acedSSAdd(ename, ss, ss);
}
long len = 0;
if (acedSSLength(ss, &len) == RTNORM && len != 0)
{
// message for debug only
//acutPrintf("Selection set ok! number of enames are: %d ", len);
ads_point p;
memcpy(CMT, AcGeMatrix3d::kIdentity.entry, sizeof(ads_matrix));
ads_name blk;
AcDbObjectId entId;
acdbTransactionManager->startTransaction();
for (int i = 0; i < len; i++)
{
acedSSName(ss, i, blk);
acdbGetObjectId(entId, blk);
AcDbEntity *pEnt = NULL;
if (acdbTransactionManager->getObject((AcDbObject*&)pEnt, entId,AcDb::kForWrite) == Acad::eOk)
{
if (acedDragGen(ss, "\nSelect insertion point: ", 0, DragFunction, p) == RTNORM)
{
acedXformSS(ss, CMT);
}
}
}
acdbTransactionManager->endTransaction();
}
acedSSFree(ss);
pRef->close();
}
}
else
{
acutPrintf("\nError on insertion= %s", sFileName, acadErrorStatusText(es));
delete pNewDb;
return;
}
//es = acDocManager->unlockDocument(acDocManager->curDocument());
//if (es != Acad::eOk) return;
}
« Last Edit: July 20, 2006, 09:42:21 PM by LE »

Alexander Rivilis

  • Bull Frog
  • Posts: 212
  • Programmer from Kyiv (Ukraine)
Re: Insert Drawing with acedDragGen() ?
« Reply #11 on: July 20, 2006, 05:36:14 PM »
And many thanks to Alexander Rivilis.... ! - for the matrix and acedDragGen sample.
:) More correct is next code for acedDragGen sample:
Code: [Select]
static ads_point Base;
static ads_matrix CMT;
static int DragFunction(ads_point pt, ads_matrix mat)
{
  AcGeVector3d v = asPnt3d(pt) - asPnt3d(Base);
  AcGeMatrix3d gMat; gMat.setToTranslation(v);
  memcpy(mat, gMat.entry, sizeof(ads_matrix));
  memcpy(CMT, mat, sizeof(ads_matrix));
  return RTNORM;
}

static void DragSamplerDragSampler(void)
{
  ads_name ss;   ads_point p;
  ads_getpoint(NULL, "\nFrom base point: ", Base);
  if (acedSSGet(NULL,NULL,NULL,NULL,ss) == RTNORM) {
    memcpy(CMT, AcGeMatrix3d::kIdentity.entry, sizeof(ads_matrix));
    if (acedDragGen(ss,"\nTo here: ",0,DragFunction,p) == RTNORM) {
      AcGeVector3d v = asPnt3d(p) - asPnt3d(Base); //  We must using returned
      AcGeMatrix3d gMat; gMat.setToTranslation(v); //  point 'p' for transforming
      memcpy(CMT, gMat.entry, sizeof(ads_matrix)); //  selection set
      acedXformSS(ss,CMT);
    }
  }
}       

MickD

  • Gator
  • Posts: 3314
  • (x-in)->[process]->(y-out)
Re: Insert Drawing with acedDragGen() ?
« Reply #12 on: July 20, 2006, 06:02:39 PM »
Nice work Guys, I just might have a use for this too. I have a 2d hlr engine (uses the hlr api) that I had to write in arx which could use this for the created linework to insert it into the drawing where user picks.
I'll give it a spin when I get time.
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: Insert Drawing with acedDragGen() ?
« Reply #13 on: July 20, 2006, 10:54:39 PM »
Update to the functions DragFunction() & insertDWG(), per later changes made by Alexander and LE.

Code: [Select]
static ads_point Base;
static ads_matrix CMT;
static int DragFunction(ads_point pt, ads_matrix mat)
{
AcGeVector3d v = asPnt3d(pt) - asPnt3d(Base);
AcGeMatrix3d gMat; gMat.setToTranslation(v);
memcpy(mat, gMat.entry, sizeof(ads_matrix));
memcpy(CMT, mat, sizeof(ads_matrix));
return RTNORM;
}

static void insertDWG (CString sFileName, CString baseName, ads_point Base)
{
Acad::ErrorStatus es;
AcDbDatabase *pNewDb = new AcDbDatabase(Adesk::kFalse);
es = acDocManager->lockDocument(acDocManager->curDocument());
if (es != Acad::eOk) return;
es = pNewDb->readDwgFile(sFileName, _SH_DENYNO, false);
if (es != Acad::eOk)
{
acutPrintf("\nError on reading file= %s", acadErrorStatusText(es));
return;
}
AcDbDatabase *pDb;
pDb = acdbHostApplicationServices()->workingDatabase();
baseName.MakeUpper();
char * pch;
pch = strstr(baseName, ".DWG");
strncpy(pch, "", 3);
AcDbObjectId blockId;
if((es = pDb->insert(blockId, baseName, pNewDb)) == Acad::eOk)
{
AcDbObjectId curSpaceId = pDb->currentSpaceId();
AcDbBlockReference *pBlockReference = new AcDbBlockReference;
pBlockReference->setBlockTableRecord(blockId);
AcDbObjectId pOutputId;
AcDbBlockTableRecord *pBlockTableRecord = NULL;
if (acdbOpenObject(pBlockTableRecord, curSpaceId, AcDb::kForWrite) == Acad::eOk)
{
pBlockTableRecord->appendAcDbEntity(pOutputId, pBlockReference);
pBlockTableRecord->close();
pBlockReference->setPosition(AcGePoint3d(Base[X], Base[Y], Base[Z]));
pBlockReference->close();
}
actrTransactionManager->flushGraphics();
acedUpdateDisplay();
AcDbBlockReference *pRef = NULL;
if (acdbOpenAcDbObject((AcDbObject *&)pRef, pOutputId, AcDb::kForWrite) == Acad::eOk)
{
AcGePoint3d ins = pRef->position();
Base[X] = ins.x;
Base[Y] = ins.y;
Base[Z] = ins.z;
ads_name ename;
ads_name ss;
acedSSAdd(NULL, NULL, ss);
es = acdbGetAdsName(ename, pOutputId);
if (es == Acad::eOk)
{
acedSSAdd(ename, ss, ss);
}
long len = 0;
if (acedSSLength(ss, &len) == RTNORM && len != 0)
{
ads_point p;
memcpy(CMT, AcGeMatrix3d::kIdentity.entry, sizeof(ads_matrix));
ads_name blk;
AcDbObjectId entId;
acdbTransactionManager->startTransaction();
for (int i = 0; i < len; i++)
{
acedSSName(ss, i, blk);
acdbGetObjectId(entId, blk);
AcDbEntity *pEnt = NULL;
if (acdbTransactionManager->getObject((AcDbObject*&)pEnt, entId,AcDb::kForWrite) == Acad::eOk)
{
if (acedDragGen(ss, "\nSelect insertion point: ", 0, DragFunction, p) == RTNORM)
{
AcGeVector3d v = asPnt3d(p) - asPnt3d(Base); //  We must using returned
AcGeMatrix3d gMat; gMat.setToTranslation(v); //  point 'p' for transforming
memcpy(CMT, gMat.entry, sizeof(ads_matrix)); //  selection set
acedXformSS(ss, CMT);
}
}
}
acdbTransactionManager->endTransaction();
}
acedSSFree(ss);
pRef->close();
}
}
else
{
acutPrintf("\nError on insertion= %s", sFileName, acadErrorStatusText(es));
delete pNewDb;
return;
}
es = acDocManager->unlockDocument(acDocManager->curDocument());
if (es != Acad::eOk) return;
}

LE

  • Guest
Re: Insert Drawing with acedDragGen() ?
« Reply #14 on: July 21, 2006, 12:46:42 AM »
I am including the C++ solution project ZIP, for Option I, a very simple approach of acdbDisplayPreviewFromDwg() implementation (not the best choice), the next step will be Option II to include a bitmap Class...

Notes:
1. ALL the code is considered academic.
2. The SLN was created using VSC++ 2002 and ObjectARX/MFC

HTH.