Chuyển đến nội dung
Diễn đàn CADViet
Detailing

[Thảo luận] Điều khiển AutoCAD bằng VC++ (ObjectARX)

Các bài được khuyến nghị

Chào bạn,

vl, vla, vlax là các hàm acet giống như 1 bộ thông dịch giữa lisp và ARX do Autodesk viết để support cho các Vlisp/lisp developer nên đương nhiên là bạn tìm ko thấy rồi :D

Nếu thấy cần những hàm đó bạn có thể viết lại dựa trên công dụng của nó

Mình nghĩ là nó phải có những hàm tương tự nhưng có thể do tên hàm khác hoặc do kg công bố thôi. Nhiều hàm chạy rát nhanh so với mình viết nên muốn tận dụng cho tiện.

 

@gia_bach : Mình cũng làm giống như bạn nhưng có lẽ do mình để tên hàm giống như lisp nên nó kg tìm đc. Mình cũng quên mất trong C kg cho tên hàm có dấu "-". Làm Lisp riết rồi lục nghề.

 

Cám ơn hai bạn.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Những bài mình post sau đây là những gì mình đã và đang học cái món này nên chắc chắn sẽ có nhiều sai sót, mong mọi người cùng nhau thảo luận.

Trước hết mình dùng VS2008 SP1 + ObjectARX SDK 2010 + test trên AutoCAD 2010

Bộ cài ObjectARX 2010 được cung cấp free bới Autodesk ở đây: http://download.auto...4_and_32Bit.exe

 

Bài học đầu tiên cho các ngôn ngữ lập trình bao giờ cũng là "Hello world" vậy mình cũng ko dám "xé rào", làm 1 cái Hello world để biết C++ và AutoCAD làm việc với nhau như thế nào. Với mục đích nhanh - gọn - lẹ mình dùng luôn wizard của AutoCAD

 

1. Chọn ObjectARX/DBX/OMF project từ project type của VS

untitled-1.jpg

 

2. Nhập Registered developer Symbol

untitled-2.jpg

 

3. Ở bảng project type chọn ObjectARX (AutoCAD Extension)

untitled-3.jpg

 

4. Không thay đổi gì cả cứ bấm Next thôi

untitled-4.jpg?w=497&h=415

 

5. Chọn No MFC support (chỉ là hello world thôi, ko cần ai support cả cool.png)

untitled-5.jpg

 

6. Không thay đổi gì cả cứ bấm Next thôi

untitled-6.jpg?w=493&h=414

 

7. Không thay đổi gì cả cứ bấm Next thôi

untitled-7.jpg

 

8. Sau khi kết thúc wizard (bấm Finish) nhìn vào solution explorer ta thấy wizard đã tạo cho ta một số file cần thiết đồng thời thết lập luôn các linker, setting, ...

untitled-8.jpg?w=361&h=368

 

9. Dùng toolbar của Autodesk để tạo command

untitled-9.jpg

 

10. Right click trên cửa sổ ObjectARX Commands -> chọn New sau đó nhập các thông tin cần thiết

untitled-10.jpg

 

11. Sau khi bấm OK trong file acrxEntryPoint.cpp ta thấy xuất hiện dòng code khai báo tên lệnh và 1 function chứa code của command

untitled-11.jpg

 

12. Add thêm dòng code này vào function mới tạo ra để hiện dòng "Welcome to ObjectARX!" trên Command của AutoCAD

 

 

 

 

13. Mở CAD lên và load lệnh thử xem thế nào (muốn dùng debug để tự mở cad thì phải add đường dẫn đến acad.exe trong properties của project)

1.gif

 

OK! thế là mình đã kết nối C++ với AutoCAD dc rồi

 

Hay đó bạn.

Cố gắng có thêm nhiều bài viết dể mọi người học hỏi nhé

Lâu rồi không lên trên này vì bận quá.

Giờ trở về nhà cùng vọc LISP với mọi người

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Mình nghĩ là nó phải có những hàm tương tự nhưng có thể do tên hàm khác hoặc do kg công bố thôi. Nhiều hàm chạy rát nhanh so với mình viết nên muốn tận dụng cho tiện.

Bạn xem mấy ý sao (ý kiến cá nhân thôi)

  1. VLA object là dump của Com object ra nhưng ARX nó làm việc trực tiếp trên Com object vậy nó xài vla làm gì?
  2. acet-ss-to-list trả về 1 list vậy ARX xài list vào việc gì trong khi nó thao tác trực tiếp với selection do nó tạo ra?
  3. vlax-curve-getclosestpoint chỉ như 1 interface (dùng cho lisp) để invoke method AcDbCurve:getClosestPointTo vậy trong ARX tại sao phải thông qua 1 interface cho lisp mà ko dùng trực tiếp method của mình?

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Bạn xem mấy ý sao (ý kiến cá nhân thôi)

  1. VLA object là dump của Com object ra nhưng ARX nó làm việc trực tiếp trên Com object vậy nó xài vla làm gì?
  2. acet-ss-to-list trả về 1 list vậy ARX xài list vào việc gì trong khi nó thao tác trực tiếp với selection do nó tạo ra?
  3. vlax-curve-getclosestpoint chỉ như 1 interface (dùng cho lisp) để invoke method AcDbCurve:getClosestPointTo vậy trong ARX tại sao phải thông qua 1 interface cho lisp mà ko dùng trực tiếp method của mình?

Mình đồng ý với bạn. Ý mình muốn hỏi chính là cái bạn nói. Cái gốc để sinh ra những hàm trên Lisp nằm chỗ nào trong Arx (trừ những hàm chuẩn mình đã biết). Mình chưa biết cách khai thác và sd nó.

Hàm acet-ss-to-list nó có ý nghĩa riêng của nó (tất nhiên hàm này viết cũng dễ nhưng nhanh chậm chưa biết), vì chính bản thân Arx cũng kg lưu giữ được cùng lúc quá 128 tập hợp chọn. Lúc đó buộc phải lưu nó ở dạng khác mà list là một ví dụ.

Trước giờ mình sd Arx chỉ toàn những hàm chuẩn. Những vđ khác mình nhờ sự hỗ trợ của Delphi thông qua DLL (chạy cũng tốt nhưng đôi khi chậm) và các lớp trong MFC (hồi đó Lisp chỉ có những hàm chuẩn-chưa có vl). Sau này thấy các bạn dùng các hàm vl, vla, ... chóng cả mặt, muốn học nhưng cũng chưa tới đâu. Nếu bạn có thể chỉ dẫn cho cách tiếp cận nó trong Arx thì hay quá. Mình là dân nghiệp dư đôi lúc dùng từ hơi thiếu chuyên môn mong bạn thông cảm

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Mình đồng ý với bạn. Ý mình muốn hỏi chính là cái bạn nói. Cái gốc để sinh ra những hàm trên Lisp nằm chỗ nào trong Arx (trừ những hàm chuẩn mình đã biết). Mình chưa biết cách khai thác và sd nó.

Hàm acet-ss-to-list nó có ý nghĩa riêng của nó (tất nhiên hàm này viết cũng dễ nhưng nhanh chậm chưa biết), vì chính bản thân Arx cũng kg lưu giữ được cùng lúc quá 128 tập hợp chọn. Lúc đó buộc phải lưu nó ở dạng khác mà list là một ví dụ.

Trước giờ mình sd Arx chỉ toàn những hàm chuẩn. Những vđ khác mình nhờ sự hỗ trợ của Delphi thông qua DLL (chạy cũng tốt nhưng đôi khi chậm) và các lớp trong MFC (hồi đó Lisp chỉ có những hàm chuẩn-chưa có vl). Sau này thấy các bạn dùng các hàm vl, vla, ... chóng cả mặt, muốn học nhưng cũng chưa tới đâu. Nếu bạn có thể chỉ dẫn cho cách tiếp cận nó trong Arx thì hay quá. Mình là dân nghiệp dư đôi lúc dùng từ hơi thiếu chuyên môn mong bạn thông cảm

Bạn có thể dùng acedInvoke() để gọi 1 function trong 1 ARX khác hoặc được defun bởi Autolisp.

Good luck!

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Bạn có thể dùng acedInvoke() để gọi 1 function trong 1 ARX khác hoặc được defun bởi Autolisp.

Good luck!

Cám ơn bạn, hàm này mình cũng đã biết dùng trong vài trường hợp rồi. Ý mình muốn tìm hiểu những hàm tương tự Lisp giống như những hàm ads vậy.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Nếu chỉ vẽ ra bỏ đấy có thể vẫn chưa thấy sự khác biệt. Nếu bạn cần lưu lại ObjectId, hoặc thông tin gì đó để update, thì ngay cả hai người dùng code arx cùng làm một chức năng thì tốc độ cũng hơn kém nhau đến cả trăm lần đó bạn :)

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Topic này rất hay sao Detailing không tiếp tục post nhỉ? Tiện đây xin hỏi TRUNGNGAMY hay menber nào có file số của Quyển Autocad và Lập trình cho ứng dụng của Thầy Bành Tiến Long - Trường ĐH Bách Khoa HN không? có thể post lên cho mọi người tham khảo được chứ. Thanks

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Topic này rất hay sao Detailing không tiếp tục post nhỉ? Tiện đây xin hỏi TRUNGNGAMY hay menber nào có file số của Quyển Autocad và Lập trình cho ứng dụng của Thầy Bành Tiến Long - Trường ĐH Bách Khoa HN không? có thể post lên cho mọi người tham khảo được chứ. Thanks

Mình kg nhớ rõ có đúng kg. Quyển này viết từ thời cad12-14. Trên đó có một phần kiến thức căn bản nói về lập trình ads cho cad (tức arx bây giờ). Các hàm chủ yếu có tiền tố ads_, tức nó tương tự hàm lisp nhưng có tiền tố ads_. Bạn có thể xem help, một số ví dụ mẫu trong bộ adsrx (cad14) hay ObjectArx (cad đời sau), biên dịch nó để ngâm cứu. Còn tài liệu dạng văn bản làm sao gởi cho bạn đây.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Đúng là quyển này Mr Long viết từ năm 1998 không biết là có mấy tập, Tập 1 gồm 2 phần 1- Giới thiệu về Autolisp, 2- giới thiệu về lập trình C cho autocad. Quyển này viết rất cơ bản. Đúng là Cad14 thì chủ yếu vẫn dùng các hàm ads là nhiều. Tiện đây xin hỏi TRUNGNGAMYDetailing là cách để Insert một Block có thuộc tính vào bản vẽ autocad thì như thế nào. Đối với Block đã có sẵn trong ban vẽ hiện thời thì mình làm được rồi. Nhưng Block chưa có thì tiền hành chèn file block đó vào bản vẽ( Cái này minh chưa làm được). Vì còn phải truy cập Database của file Block đó nữa. các bạn có thể code demo cho mình tham khảo được không. Thanks

PS: Mà để code nhanh VC thì có thể dùng Add-in Visual Assis X để gợi nhớ code cho nhanh, cái này hạn chế được rất nhiều lỗi khi code đấy.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Mình đang viết một đoạn code để Insert Block (là file DWG) vào bản vẽ, nhưng đang bị lỗi, các menber sửa giúp mình với

 

void adskInsertBlock()

{

ACHAR* szName = _T("luanuoc");

ACHAR *fileName = _T("C:\\procad\\dwg\\luanuoc.dwg");

AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();

AcDbDatabase *pBlockDb = new AcDbDatabase(false,true);

pBlockDb ->readDwgFile(fileName,_SH_DENYRW,true);

AcDbBlockTable *BlkTable;

AcDbObjectId BlkId;

//AcDbObjectIdArray Ids = new AcDbObjectIdArray();

//BlkId =pBlockDb ->blockTableId();

BlkTable ->getAt(ACDB_MODEL_SPACE,BlkId,AcDb::kForRead);

pDb->insert(BlkId,szName,pBlockDb,true);

if (BlkTable->has(BlkId))

{

ads_point p;

acutPrintf("\nDa co Block %s",szName);

acedGetPoint(NULL,"Chon diem chen",p);

AcGePoint3d Inspoint(p[X],p[Y],p[Z]);

AcDbBlockReference *pBlockobj = new AcDbBlockReference;

AcDbBlockTableRecord *pBlkTablerec;

pBlockobj ->setBlockTableRecord(BlkId);

pBlockobj ->setPosition(Inspoint);

pBlockobj ->setScaleFactors(1);

BlkTable ->getAt(ACDB_MODEL_SPACE,pBlkTablerec,AcDb::kForWrite);

BlkTable ->close();

pBlkTablerec ->appendAcDbEntity(pBlockobj);

pBlkTablerec ->close();

pBlockobj ->close();

acutPrintf("\nDa chen Block %s vao ban ve",szName);

 

}

Thanks

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Mình chỉ quen cách viết ads thôi, nó giống lisp. Ví dụ viết hàm tạo một loạt các điểm ranh đất theo thứ tự điểm được cung cấp trong một array

 

int VeTruranh(ads_point *ar, int lr, double tlbd)

{

ads_point p;

for (int i=0;i<lr-1;i++) {

p[0]=ar[0];p[1]=ar[1];

ads_command(RTSTR,"_.insert",RTSTR,"truranh",RTSTR,"s",RTREAL,tlbd/1000.0,RTPOINT,p,RTREAL,0.0,RTSTR,ads_itoa(i+1),RTNONE);

}

return 0;

}

trong đó :

- "truranh" là tên file (block) có thuộc tính là số hiệu điểm, nó phải có trên bv hoặc trong đường dẫn cad

- tlbd: là tỷ lệ bản đồ.

- ads_itoa( int) : hàm đổi số nguyên thành chuỗi

Cách viết như của bạn mình không rành lắm, đang học hỏi, hôm nào bạn hoàn chỉnh thì mình copy về tham khảo thôi

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Mình đang viết một đoạn code để Insert Block (là file DWG) vào bản vẽ, nhưng đang bị lỗi, các menber sửa giúp mình với

 

void adskInsertBlock()

{

ACHAR* szName = _T("luanuoc");

ACHAR *fileName = _T("C:\\procad\\dwg\\luanuoc.dwg");

AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();

AcDbDatabase *pBlockDb = new AcDbDatabase(false,true);

pBlockDb ->readDwgFile(fileName,_SH_DENYRW,true);

AcDbBlockTable *BlkTable;

AcDbObjectId BlkId;

//AcDbObjectIdArray Ids = new AcDbObjectIdArray();

//BlkId =pBlockDb ->blockTableId();

BlkTable ->getAt(ACDB_MODEL_SPACE,BlkId,AcDb::kForRead);

pDb->insert(BlkId,szName,pBlockDb,true);

if (BlkTable->has(BlkId))

{

ads_point p;

acutPrintf("\nDa co Block %s",szName);

acedGetPoint(NULL,"Chon diem chen",p);

AcGePoint3d Inspoint(p[X],p[Y],p[Z]);

AcDbBlockReference *pBlockobj = new AcDbBlockReference;

AcDbBlockTableRecord *pBlkTablerec;

pBlockobj ->setBlockTableRecord(BlkId);

pBlockobj ->setPosition(Inspoint);

pBlockobj ->setScaleFactors(1);

BlkTable ->getAt(ACDB_MODEL_SPACE,pBlkTablerec,AcDb::kForWrite);

BlkTable ->close();

pBlkTablerec ->appendAcDbEntity(pBlockobj);

pBlkTablerec ->close();

pBlockobj ->close();

acutPrintf("\nDa chen Block %s vao ban ve",szName);

 

}

Thanks

Block table ban chua co lay ve tu database hien tai ma, chi moi co khai bao 1 pointer roi tu nhien su dung luon.

AcDbBlockTable *BlkTable;

Acad::ErrorStatus es = pDb->getSymbolTable(BlkTable, AcDb::kForRead);

// luc nay moi su dung block table de lay ve model space nhu tren dc

BlkTable->close();

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Code Insert 1 Block từ 1 bản vẽ khác vào bản vẽ Active.

 

static void th_ArxProject1_HelloWorld_InsertBlock(void)

{

// Add your code for command th_ArxProject1_HelloWorld._InsertBlock here

AcDbDatabase *pDbSource = new AcDbDatabase(Adesk::kFalse);

 

ACHAR *fName = _T("D:\\DwgEx.dwg");

ACHAR *BlkName = _T("dirpoint");

 

Acad::ErrorStatus err = pDbSource->readDwgFile(fName);

if(err != Acad::eOk)

{

delete pDbSource;

return;

}

AcDbDatabase *pDbDest = acdbHostApplicationServices()->workingDatabase();

 

AcDbObjectId Id = getBlockId(pDbSource, pDbDest, BlkName);

delete pDbSource;

 

if(Id==AcDbObjectId::kNull)

return;

 

AcDbBlockTable *pBlkTbl;

pDbDest->getBlockTable(pBlkTbl, AcDb::kForRead);

 

AcDbBlockTableRecord *pmdl;

pBlkTbl->getAt(ACDB_MODEL_SPACE, pmdl, AcDb::kForWrite);

pBlkTbl->close();

 

ads_point p;

int ret = acedGetPoint(NULL, _T("\nSpecify Point to Insert:"),p);

if(ret!=RTNORM) return;

 

AcGePoint3d Inspoint(p[X], p[Y], p[Z]);

AcDbBlockReference *pBlockobj = new AcDbBlockReference;

 

pBlockobj->setBlockTableRecord(Id);

pBlockobj->setPosition(Inspoint);

pmdl->appendAcDbEntity(pBlockobj);

pmdl->close();

pBlockobj->close();

}

 

static

AcDbObjectId getBlockId(AcDbDatabase *pSourceDb,

AcDbDatabase *pTargetDb,

ACHAR *sSourceBlock)

{

AcDbObjectId idBlock = AcDbObjectId::kNull;

if (AcDbSymbolUtilities::getBlockId(idBlock,sSourceBlock,pSourceDb)!=Acad::eOk)

{

return idBlock;

}

 

AcDbDatabase * pOutputDb = NULL;

if (pSourceDb->wblock(pOutputDb, idBlock)!=Acad::eOk)

{

delete pOutputDb;

return AcDbObjectId::kNull;

}

 

if (pTargetDb->insert(idBlock,sSourceBlock,pOutputDb,true)!=Acad::eOk)

{

delete pOutputDb;

return AcDbObjectId::kNull;

}

delete pOutputDb;

 

return idBlock;

}

 

ps: Tên bản vẽ lưu trong fName, ten Block lưu trong BlkName

tested trên ACAD 2010 (R18)

Goodluck!

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Code của Detailing là Insert một Block có trong một bản vẽ khác vào bản vẽ Active;

Còn yêu cầu của mình là insert Block có tên là szBlock vào file với điều kiện

1. Kiểm tra nếu Block chưa có trong bản vẽ thì tiến hành chèn file szDwg=szBlock.dwg vào Database của Bản vẽ Active.

2. tiến hành chèn szBlock từ Database vào ModelSpace;

Đây là code mình đã sửa. Các bạn test thử nha:

 

void adskInsertBlock()

{

TCHAR *szBlock;

TCHAR *szDwg;

szBlock = _T("caycn");

szDwg =_T("C:\\Procad\\dwg\\caycn.dwg");

CheckBlock(szBlock,szDwg);

ads_point p1;

acedGetPoint(NULL,_T("chon diem chen"),p1);

AcGePoint3d Inspoint(p1[X],p1[Y],p1[Z]);

AcDbBlockTable *pBlkTable=NULL;

AcDbBlockTableRecord *pBlkTablerec;

AcDbDatabase *pCurDb = NULL;

AcGeScale3d Tile(1,1,1);

pCurDb = acdbHostApplicationServices()->workingDatabase();

pCurDb ->getSymbolTable(pBlkTable,AcDb::kForRead);

AcDbObjectId BlkId;

pBlkTable ->getAt(szBlock,BlkId);

if(pBlkTable->has(szBlock))

{

AcDbBlockReference *pBlockobj = new AcDbBlockReference;

pBlockobj ->setBlockTableRecord(BlkId);

pBlockobj ->setPosition(Inspoint);

pBlockobj ->setScaleFactors(Tile);

pBlkTable ->getAt(ACDB_MODEL_SPACE,pBlkTablerec,AcDb::kForWrite);

pBlkTable ->close();

pBlkTablerec ->appendAcDbEntity(pBlockobj);

pBlkTablerec ->close();

pBlockobj ->close();

acutPrintf("\nDa chen Block vao ban ve");

}

 

}

/* Ham kiem tra xem Block da co trong ban ve chua?

Neu chua co thi chen trong file vao*/

 

void CheckBlock( TCHAR *szBlock, TCHAR *szDwg)

{

AcDbDatabase *pBlockDb=NULL;

AcDbObjectId pBlockId;

AcDbDatabase *pDb=NULL;

 

pDb = acdbHostApplicationServices()->workingDatabase();

 

 

 

if ( CheckBlockExist( szBlock ))

{

return;

}

pBlockDb = new AcDbDatabase( Adesk::kFalse );

if ( pBlockDb->readDwgFile(szDwg) != Acad::eOk )

{

delete pBlockDb;

return;

}

 

 

pDb->insert( pBlockId, szBlock, pBlockDb );

delete pBlockDb;

//delete pDb;

return;

}

 

//------------------------------------//

// Kiem tra Block co ton tai khong //

//------------------------------------//

int CheckBlockExist( TCHAR *szBlock )

{

AcDbBlockTable *pBlockTable;

AcDbBlockTableRecord *pBlockTableRecord;

int nRet;

AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();

pDb->getBlockTable( pBlockTable, AcDb::kForRead );

 

// Get Pointer to This Blocks BlockTableRecord

nRet = pBlockTable->getAt( szBlock, pBlockTableRecord, AcDb::kForRead );

pBlockTable->close();

 

if ( nRet != Acad::eOk ) {

return( FALSE );

} else {

pBlockTableRecord->close();

return( TRUE );

}

}

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Vấn đề đặt ra là nếu Block Attributes thì đoạn code trên cần bổ sung những gì để có thể chèn các Textstring cho Attributes. Detailing xem bổ sung cho mình với! Thanks

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Không bạn nào tham gia cả :(

 

function Update Attribute cho Block

static

void UpdateAttribute(AcDbBlockReference *pBlkRef)

{

AcDbBlockTableRecord *pBlockDef;

acdbOpenObject(pBlockDef, pBlkRef->blockTableRecord(), AcDb::kForRead);

 

AcDbBlockTableRecordIterator *pIterator;

pBlockDef->newIterator(pIterator);

AcDbEntity *pEnt;

AcDbAttributeDefinition *pAttdef;

for (pIterator->start(); !pIterator->done();

pIterator->step())

{

pIterator->getEntity(pEnt, AcDb::kForRead);

 

pAttdef = AcDbAttributeDefinition::cast(pEnt);

if (pAttdef != NULL && !pAttdef->isConstant())

{

AcDbAttribute *pAtt = new AcDbAttribute();

pAtt->setPropertiesFrom(pAttdef);

pAtt->setInvisible(pAttdef->isInvisible());

 

AcGePoint3d basePoint = pAttdef->position();

basePoint += pBlkRef->position().asVector();

pAtt->setPosition(basePoint);

pAtt->setHeight(pAttdef->height());

pAtt->setRotation(pAttdef->rotation());

pAtt->setTag( pAttdef->tag());

pAtt->setTextString(_T("TEST ATT"));

AcDbObjectId attId;

pBlkRef->appendAttribute(attId, pAtt);

pAtt->close();

}

pEnt->close();

}

delete pIterator;

pBlockDef->close();

pBlkRef->close();

}

 

Thêm lời gọi hàm trong code trên

....................................

 

pmdl->appendAcDbEntity(pBlockobj);

 

UpdateAttribute(pBlockobj);

 

pmdl->close();

...........................................

 

 

Good luck!

 

p/s: Block insert cần có Att : tag = TAG

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Mình cũng đã hoàn thành đoạn code này. các bạn text thử nhé.

Hàm này có kiểm tra xem Block có trong bản vẽ hay không? nếu có thì chèn luôn, nếu không có thì chèn theo file với đường dẫn cho trước.

/* Ham kiem tra xem Block da co trong ban ve chua?

Neu chua co thi chen trong file vao*/

void

ProcadUtil::CheckBlock(char *szBlock, char *szDwg)

{

AcDbDatabase *pBlockDb=NULL;

AcDbObjectId pBlockId;

AcDbDatabase *pDb=NULL;

 

pDb = acdbHostApplicationServices()->workingDatabase();

 

// If it Already Exists, Exit

 

if ( CheckBlockExist( szBlock ))

{

return;

}

pBlockDb = new AcDbDatabase( Adesk::kFalse );

if ( pBlockDb->readDwgFile(szDwg) != Acad::eOk )

{

delete pBlockDb;

return;

}

 

// Insert this new Drawing as a Block in the Current Database

pDb->insert( pBlockId, szBlock, pBlockDb );

delete pBlockDb;

//delete pDb;

return;

}

 

//------------------------------------//

// DoesBlockExist //

//------------------------------------//

int

ProcadUtil::CheckBlockExist( char *szBlock )

{

AcDbBlockTable *pBlockTable;

AcDbBlockTableRecord *pBlockTableRecord;

int nRet;

AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();

pDb->getBlockTable( pBlockTable, AcDb::kForRead );

 

// Get Pointer to This Blocks BlockTableRecord

nRet = pBlockTable->getAt( szBlock, pBlockTableRecord, AcDb::kForRead );

pBlockTable->close();

 

if ( nRet != Acad::eOk ) {

return( FALSE );

} else {

pBlockTableRecord->close();

return( TRUE );

}

}

void

ProcadUtil::InsertKH1(char *szBlock, char *szDwg, double x, double y, double elev,int stt, double Tile,double goc)

{

CheckBlock(szBlock,szDwg);

AcGePoint3d Inspoint(x,y,elev);

AcGePoint3d BasePoint;

AcGePoint3d BasePoint1;

AcDbBlockTable *pBlkTable=NULL;

AcDbBlockTableRecord *pBlkTablerec;

AcDbDatabase *pCurDb = NULL;

AcGeScale3d TileScale(Tile,Tile,Tile);

pCurDb = acdbHostApplicationServices()->workingDatabase();

pCurDb ->getSymbolTable(pBlkTable,AcDb::kForRead);

AcDbObjectId BlkId;

pBlkTable ->getAt(szBlock,BlkId);

if(pBlkTable->has(szBlock))

{

AcDbBlockReference *pBlockobj = new AcDbBlockReference;

pBlockobj ->setBlockTableRecord(BlkId);

/*struct resbuf to,from;

from.restype=RTSHORT;

from.resval.rint=1;

to.restype=RTSHORT;

to.resval.rint=0;

AcGeVector3d normal(0.0,0.0,1.0);

acedTrans(&(normal.x),&from,&to,Adesk::kTrue,&(normal.y));*/

pBlockobj ->setPosition(Inspoint);

pBlockobj ->setScaleFactors(Tile);

pBlkTable ->getAt(ACDB_MODEL_SPACE,pBlkTablerec,AcDb::kForWrite);

pBlkTable ->close();

AcDbObjectId pEntId;

pBlkTablerec ->appendAcDbEntity(pEntId,pBlockobj);

pBlkTablerec ->close();

// Open BlockRef do doc du lieu Attributes.

AcDbBlockTableRecord *pBlockDef;

acdbOpenObject(pBlockDef,BlkId,AcDb::kForRead);

//Cai dat 1 Block Table Record bien lap

// Duyet qua cac Attributes Definitions de kiem tra va gan du lieu

AcDbBlockTableRecordIterator *pItr;

pBlockDef->newIterator(pItr);

AcDbEntity *pEnt;

AcDbAttributeDefinition *pAttDef;

// Vong lap duyet qua cac pItr;

for (pItr->start(); !pItr->done();pItr->step())

{

// Get the next entity.

//

pItr->getEntity(pEnt,AcDb::kForRead);

// Kiem tra xem doi tuong co phai la Block Attributes khong?

//

pAttDef =AcDbAttributeDefinition::cast(pEnt);

if (pAttDef!=NULL)

{

char *pStr=pAttDef->tag();

 

if(_strcmpi(pStr,_T("TENDIEM"))==0)

{

AcDbAttribute *pAtt=new AcDbAttribute;

pAtt->setPropertiesFrom(pAttDef);

BasePoint =pAttDef->position();

BasePoint += pBlockobj->position().asVector();

pAtt->setPosition(BasePoint);

pAtt->setTag(pStr);

pAtt->setTextString("DC12");

pAtt->setHeight(pAttDef->height());

pAtt->setHorizontalMode(AcDb::TextHorzMode::kTextLeft);

pAtt->setVerticalMode(AcDb::TextVertMode::kTextBase);

//pAtt->setc

AcDbObjectId AttId;

pBlockobj->appendAttribute(AttId,pAtt);

pAtt->close();

 

 

}

if(_strcmpi(pStr,_T("DOCAO"))==0)

{

AcDbAttribute *pAtt1= new AcDbAttribute;

pAtt1->setPropertiesFrom(pAttDef);

BasePoint1 =pAttDef->position();

BasePoint1 += pBlockobj->position().asVector();

pAtt1->setPosition(BasePoint1);

//pAtt1->setPosition(pAttDef->position());

pAtt1->setTag(pStr);

pAtt1->setTextString("126.635");

pAtt1->setHeight(pAttDef->height());

pAtt1->setHorizontalMode(AcDb::TextHorzMode::kTextLeft);

pAtt1->setVerticalMode(AcDb::TextVertMode::kTextBase);

AcDbObjectId AttId1;

pBlockobj->appendAttribute(AttId1,pAtt1);

pAtt1->close();

 

 

}

free(pStr);

 

}

pEnt->close();

}

delete pItr;

pAttDef->close();

 

pBlockobj->close();

 

}

}

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Bạn cần phải cài VS2008 SP1 chú ý cái SP1 trước sau đó cài ARX SDK tự nhiênn sẽ có ARX wizard trong VS

Goodluck ! :D

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Thank a Detailing. e đã cài được rùi

cho e hỏi thêm cái cách liên kết arx với cad với ạ(cụ thể từ bước thứ 12 trở đi). e làm như a Detailing nói nhưng đến bước thứ 13(đầu topic) thì cad lại không load được(chắc không đúng đường dẫn) :(

và cái code của arx trong VS2008 thì viết ở đoạn nào? e mới học cái này, cũng đang đọc tài liệu về nó

PS: e dùng VS2008 SP1 và autocad 2012

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Thank a Detailing. e đã cài được rùi

cho e hỏi thêm cái cách liên kết arx với cad với ạ(cụ thể từ bước thứ 12 trở đi). e làm như a Detailing nói nhưng đến bước thứ 13(đầu topic) thì cad lại không load được(chắc không đúng đường dẫn) :(

và cái code của arx trong VS2008 thì viết ở đoạn nào? e mới học cái này, cũng đang đọc tài liệu về nó

PS: e dùng VS2008 SP1 và autocad 2012

Do AutoCAD 2012 được build bằng VS2010 nên mình nghĩ bạn nên sử dụng VS2010 và Object ARX 2012.

Đoạn code đó viết vào chỗ  ""Add your code for command ......"

Goodluck!

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

cái code của .arx  phải Buil qua C sau mới dùng Lệnh ap của cad để load file .arx vào Cad

 vậy có cách khác để lúc ấn F5 thì tự ARX chạy sang Cad không ạ?

ví dụ như có 1 file hơi lớn 1 tí thì muốn View nó chạy như thế nào cũng phải Buil qua C,như vậy thì bất tiện quá.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Bạn Detailing cho mình hỏi là giữa C#.Net, VB.Net và Object ARX thì nên chọn học thằng nào. Tại mình có đọc đâu đó một bài của bạn nói Object ARX tuy rằng mạnh nhất, được Autodesk dùng để phát triển cad nhưng lại khó sử dụng hơn .Net 

Thanks !

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Tạo một tài khoản hoặc đăng nhập để nhận xét

Bạn cần phải là một thành viên để lại một bình luận

Tạo tài khoản

Đăng ký một tài khoản mới trong cộng đồng của chúng tôi. Điều đó dễ mà.

Đăng ký tài khoản mới

Đăng nhập

Bạn có sẵn sàng để tạo một tài khoản ? Đăng nhập tại đây.

Đăng nhập ngay

×