ObjectARX

Reply
Active Contributor
majklha
Posts: 48
Registered: ‎06-16-2008
Message 1 of 3 (653 Views)
Accepted Solution

read a SHX file to acad

653 Views, 2 Replies
05-04-2009 02:33 PM
How to read shx file (file with shapes definition) to acad, using C++ (I can it do with acedCommand).
I need it for linetypes.. In acad you can do by command _load.
Thanks
Note that this code was written before "Unicode revolution" in AutoCAD and you have to support unicode.
{code}
static void CreateMyLineType(void)
{
Acad::ErrorStatus es;
// Finding AcDbTextStyleTableRecord for ltypeshp.shx.
// This file must be in support path's of AutoCAD
AcDbTextStyleTablePointer pTT(acdbCurDwg(),AcDb::kForRead);
if (pTT.openStatus() == Acad::eOk) {
AcDbObjectId ttId;
AcDbTextStyleTableIterator *iter = NULL;
if ((es = pTT->newIterator(iter)) != Acad::eOk) {
acutPrintf("\npTT->newIterator(iter)=%s",acadErrorStatusText(es));
return;
}
for (iter->start();!iter->done(); iter->step()) {
AcDbTextStyleTableRecord *pTTR=NULL;
if ((es = iter->getRecord(pTTR,AcDb::kForRead)) != Acad::eOk) {
acutPrintf("\niter->getRecord(pTTR,AcDb::kForRead)=%s",acadErrorStatusText(es));
delete iter;
return;
}
const char *fname = NULL;
pTTR->fileName(fname);
if (!stricmp(fname,"ltypeshp.shx")) {
ttId = pTTR->objectId();
pTTR->close();
break;
}
pTTR->close();
}
delete iter;
//
// If there is no AcDbTextStyleTableRecord for ltypeshp.shx - creating it.
//
if (ttId.isNull()) {
if (pTT->upgradeOpen() != Acad::eOk) {
return;
}
AcDbTextStyleTableRecord *pTTR = new AcDbTextStyleTableRecord();
pTTR->setFileName("ltypeshp.shx");
pTTR->setIsShapeFile(true);
if ((es = pTT->add(ttId,pTTR)) != Acad::eOk) {
acutPrintf("\npTT->add(ttId,pTTR)=%s",acadErrorStatusText(es));
delete pTTR;
return;
}
pTTR->close();
}
pTT->close();
//
// Creating LineType
//
AcDbLinetypeTablePointer pLT(acdbCurDwg(),AcDb::kForRead);
if ((es = pLT.openStatus()) != Acad::eOk) {
acutPrintf("\npLT.openStatus()=%s",acadErrorStatusText(es));
return;
}
AcDbObjectId ltrid;
if (pLT->getAt("MY_LINETYPE",ltrid) == Acad::eOk) {
acutPrintf("\nMY_LINETYPE linetype is existing!");
return;
}
if ((es = pLT->upgradeOpen()) != Acad::eOk) {
acutPrintf("\npLT->upgradeOpen()=%s",acadErrorStatusText(es));
return;
}
AcDbLinetypeTableRecord *pLTR = new AcDbLinetypeTableRecord();
pLTR->setName("MY_LINETYPE");
pLTR->setComments("My own linetype");
pLTR->setPatternLength(36.83);
pLTR->setNumDashes(4);
pLTR->setDashLengthAt(0,6.35);
pLTR->setDashLengthAt(1,-2.54);
pLTR->setShapeNumberAt(1,133);
pLTR->setShapeStyleAt(1,ttId);
pLTR->setShapeOffsetAt(1,AcGeVector2d(-2.54,0));
pLTR->setShapeScaleAt(1,2.54);
pLTR->setDashLengthAt(2,-2.54);
pLTR->setDashLengthAt(3,25.4);
if ((es = pLT->add(ltrid,pLTR)) != Acad::eOk) {
acutPrintf("\npLT->add(ltrid,pLTR)=%s",acadErrorStatusText(es));
delete pLTR;
}
pLTR->close();
}
}
static void ShapeNames(void)
{
struct SHAPESTRUCT {
unsigned short iShapeNumber; // shape number
unsigned short iDefBytes; // number of data bytes in shape, 2000 max
unsigned char *lpszShapeName; // pointer to shapename
unsigned char *lpszSpecBytes; // pointer to shape specification bytes
};
char SHAPE10[] = "AutoCAD-86 shapes 1.0";
char SHAPE11[] = "AutoCAD-86 shapes 1.1";
resbuf *rbfile = NULL;
if (RTNORM == acedGetFileNavDialog("Select shape file","","shx","ShapeNames",0,&rbfile))
{
FILE *fshx = fopen(rbfile->resval.rstring,"rb"); acutRelRb(rbfile);
if (fshx) {
char desc[32];
fread (desc,sizeof(desc),1,fshx);
if (!strstr(desc,SHAPE10) && !strstr(desc,SHAPE11)) {
acutPrintf("\nIt is not shape file!");
fclose(fshx);
return;
}
fseek (fshx, (long)0x1c, SEEK_SET);
unsigned short iNumShapes = 0;
fread (&iNumShapes, sizeof (iNumShapes), 1, fshx);
SHAPESTRUCT *lpShapeList, *lpShape;
lpShapeList = (SHAPESTRUCT *)calloc(iNumShapes, sizeof (*lpShapeList));
for (int i=0; i < iNumShapes; i++) {
lpShape = lpShapeList + i;
fread(&(lpShape->iShapeNumber), sizeof (lpShape->iShapeNumber), 1, fshx);
fread(&(lpShape->iDefBytes), sizeof (lpShape->iDefBytes), 1, fshx);
}
if (lpShapeList->iShapeNumber != 0) { // Это файл формы
for (int i = 0; i < iNumShapes; i++) {
lpShape = lpShapeList + i;
lpShape->lpszShapeName = (unsigned char *)(malloc (lpShape->iDefBytes));
fread (lpShape->lpszShapeName, sizeof (*lpShape->lpszShapeName), lpShape->iDefBytes, fshx);
acutPrintf("\nShape N%d = %s", i, lpShape->lpszShapeName);
free(lpShape->lpszShapeName);
}
} else {
acutPrintf("\nIt is not shape file!");
}
free(lpShapeList);
fclose(fshx);
}
}
}
{code} Edited by: AlexanderRivilis on May 8, 2009 11:39 AM
*Art Cooney
Message 2 of 3 (653 Views)

Re: read a SHX file to acad

05-07-2009 08:21 PM in reply to: majklha

I believe that the only way to load an shx is via
acedCommand().


style="PADDING-RIGHT: 0px; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
How
to read shx file (file with shapes definition) to acad, using C++ (I can it do
with acedCommand). I need it for linetypes.. In acad you can do by command
_load. Thanks
Valued Contributor
AlexanderRivilis
Posts: 71
Registered: ‎08-31-2007
Message 3 of 3 (653 Views)

Re: read a SHX file to acad

05-07-2009 11:49 PM in reply to: majklha
Note that this code was written before "Unicode revolution" in AutoCAD and you have to support unicode.
{code}
static void CreateMyLineType(void)
{
Acad::ErrorStatus es;
// Finding AcDbTextStyleTableRecord for ltypeshp.shx.
// This file must be in support path's of AutoCAD
AcDbTextStyleTablePointer pTT(acdbCurDwg(),AcDb::kForRead);
if (pTT.openStatus() == Acad::eOk) {
AcDbObjectId ttId;
AcDbTextStyleTableIterator *iter = NULL;
if ((es = pTT->newIterator(iter)) != Acad::eOk) {
acutPrintf("\npTT->newIterator(iter)=%s",acadErrorStatusText(es));
return;
}
for (iter->start();!iter->done(); iter->step()) {
AcDbTextStyleTableRecord *pTTR=NULL;
if ((es = iter->getRecord(pTTR,AcDb::kForRead)) != Acad::eOk) {
acutPrintf("\niter->getRecord(pTTR,AcDb::kForRead)=%s",acadErrorStatusText(es));
delete iter;
return;
}
const char *fname = NULL;
pTTR->fileName(fname);
if (!stricmp(fname,"ltypeshp.shx")) {
ttId = pTTR->objectId();
pTTR->close();
break;
}
pTTR->close();
}
delete iter;
//
// If there is no AcDbTextStyleTableRecord for ltypeshp.shx - creating it.
//
if (ttId.isNull()) {
if (pTT->upgradeOpen() != Acad::eOk) {
return;
}
AcDbTextStyleTableRecord *pTTR = new AcDbTextStyleTableRecord();
pTTR->setFileName("ltypeshp.shx");
pTTR->setIsShapeFile(true);
if ((es = pTT->add(ttId,pTTR)) != Acad::eOk) {
acutPrintf("\npTT->add(ttId,pTTR)=%s",acadErrorStatusText(es));
delete pTTR;
return;
}
pTTR->close();
}
pTT->close();
//
// Creating LineType
//
AcDbLinetypeTablePointer pLT(acdbCurDwg(),AcDb::kForRead);
if ((es = pLT.openStatus()) != Acad::eOk) {
acutPrintf("\npLT.openStatus()=%s",acadErrorStatusText(es));
return;
}
AcDbObjectId ltrid;
if (pLT->getAt("MY_LINETYPE",ltrid) == Acad::eOk) {
acutPrintf("\nMY_LINETYPE linetype is existing!");
return;
}
if ((es = pLT->upgradeOpen()) != Acad::eOk) {
acutPrintf("\npLT->upgradeOpen()=%s",acadErrorStatusText(es));
return;
}
AcDbLinetypeTableRecord *pLTR = new AcDbLinetypeTableRecord();
pLTR->setName("MY_LINETYPE");
pLTR->setComments("My own linetype");
pLTR->setPatternLength(36.83);
pLTR->setNumDashes(4);
pLTR->setDashLengthAt(0,6.35);
pLTR->setDashLengthAt(1,-2.54);
pLTR->setShapeNumberAt(1,133);
pLTR->setShapeStyleAt(1,ttId);
pLTR->setShapeOffsetAt(1,AcGeVector2d(-2.54,0));
pLTR->setShapeScaleAt(1,2.54);
pLTR->setDashLengthAt(2,-2.54);
pLTR->setDashLengthAt(3,25.4);
if ((es = pLT->add(ltrid,pLTR)) != Acad::eOk) {
acutPrintf("\npLT->add(ltrid,pLTR)=%s",acadErrorStatusText(es));
delete pLTR;
}
pLTR->close();
}
}
static void ShapeNames(void)
{
struct SHAPESTRUCT {
unsigned short iShapeNumber; // shape number
unsigned short iDefBytes; // number of data bytes in shape, 2000 max
unsigned char *lpszShapeName; // pointer to shapename
unsigned char *lpszSpecBytes; // pointer to shape specification bytes
};
char SHAPE10[] = "AutoCAD-86 shapes 1.0";
char SHAPE11[] = "AutoCAD-86 shapes 1.1";
resbuf *rbfile = NULL;
if (RTNORM == acedGetFileNavDialog("Select shape file","","shx","ShapeNames",0,&rbfile))
{
FILE *fshx = fopen(rbfile->resval.rstring,"rb"); acutRelRb(rbfile);
if (fshx) {
char desc[32];
fread (desc,sizeof(desc),1,fshx);
if (!strstr(desc,SHAPE10) && !strstr(desc,SHAPE11)) {
acutPrintf("\nIt is not shape file!");
fclose(fshx);
return;
}
fseek (fshx, (long)0x1c, SEEK_SET);
unsigned short iNumShapes = 0;
fread (&iNumShapes, sizeof (iNumShapes), 1, fshx);
SHAPESTRUCT *lpShapeList, *lpShape;
lpShapeList = (SHAPESTRUCT *)calloc(iNumShapes, sizeof (*lpShapeList));
for (int i=0; i < iNumShapes; i++) {
lpShape = lpShapeList + i;
fread(&(lpShape->iShapeNumber), sizeof (lpShape->iShapeNumber), 1, fshx);
fread(&(lpShape->iDefBytes), sizeof (lpShape->iDefBytes), 1, fshx);
}
if (lpShapeList->iShapeNumber != 0) { // Это файл формы
for (int i = 0; i < iNumShapes; i++) {
lpShape = lpShapeList + i;
lpShape->lpszShapeName = (unsigned char *)(malloc (lpShape->iDefBytes));
fread (lpShape->lpszShapeName, sizeof (*lpShape->lpszShapeName), lpShape->iDefBytes, fshx);
acutPrintf("\nShape N%d = %s", i, lpShape->lpszShapeName);
free(lpShape->lpszShapeName);
}
} else {
acutPrintf("\nIt is not shape file!");
}
free(lpShapeList);
fclose(fshx);
}
}
}
{code} Edited by: AlexanderRivilis on May 8, 2009 11:39 AM
 
Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Do you have 60 seconds to spare? The Autodesk Community Team is revamping our site ranking system and we want your feedback! Please click here to launch the 5 question survey. As always your input is greatly appreciated.