Trang

Hiển thị các bài đăng có nhãn Thu thuat objectARX. Hiển thị tất cả bài đăng
Hiển thị các bài đăng có nhãn Thu thuat objectARX. Hiển thị tất cả bài đăng

Thứ Hai, 1 tháng 7, 2013

Chuyển đổi các dạng chuỗi ký tự trong ObjectARX và VS2005

Một vấn đề làm nhức nhối dân lập trình nghiệp dư như mình là chuyển đổi giữa các dạng ký tự (char, TCHAR, ACHAR, wtchar, string, CString, UNICODE, ANSI...). Nhiều lúc mình không phân biệt nổi, dẫn đến những lỗi rất ngớ ngẩn khi chạy ứng dụng ObjectARX. Những lỗi này có thể làm cho AutoCAD ngừng hoạt động theo kiểu "đột quỵ", ra đi không một lời từ biệt.
Nhưng con giun xéo lắm cũng phải oằn, hôm nay mình sẽ quyết tâm tìm hiểu đến nơi đến chốn vấn đề này.

Dưới đây là một số hàm chuyển đổi mình đã sưu tập được:

1. Sử dụng kiểu string phải thêm tệp tin tiêu đề string.h
# Include "string"
using namespace std;

2. Tương tự, khi sử dụng kiểu CString cũng phải thêm tệp tin tiêu đề (trong dự án không có MFC)
# Include "afx.h"
Chú ý Nếu gặp thông báo lỗi:
 # error: Building MFC application with / MD [d] (CRT dll version) requires MFC shared dll version. Please # define _AFXDLL Or do not use / MD [d] error.
Lúc này, bạn cần thay đổi cài đặt cho dự án:

Project | Properties | Configuration Properties | General | Use of MFC:
Use MFC in a Shared DLL (Project -> Properties -> Lựa chọn Use MFC in as share dll)

Sử dụng MFC cho dự án
3. wchar_t
wchar_t là một kiểu dữ liệu của C++, char is 8 character type, có thể chứa tới 256 loại Character, nhiều nhóm ký tự nước ngoài đặt số ký tự còn lớn hơn 256,  many foreign-language character sets the number of characters contained more than 256, character can not be represented

wchar_t data type is 16, the number of characters that can be represented far more than the char type.

4. Kiểu ACHAR (đây là kiểu dữ liệu được định nghĩa bởi AUTODESK trong tệp tin adachar.h:
typedef wchar_t ACHAR ;)
# include "adachar.h"

5. USES_CONVERSION được định nghĩa trong tệp tin atlconv.h
#include "atlconv.h"

6. Chuyển đổi từ string sang ACHAR *

string str = "string";
ACHAR * ach;
USES_CONVERSION;
ach = (ACHAR *) A2CT (str.c_str ());
7. Chuyển đổi từ ACHAR * sang string
ACHAR * ach;
USES_CONVERSION;
string temp = W2A (ach);

8. Chuyển đổi từ (Wchar_t) ACHAR * sang char *
char * ch;
ACHAR * ach;
USES_CONVERSION;
ch = T2A (ach);

9. Chuyển đổi từ char * sang ACHAR *
ACHAR * ach1;
char * ch;
Cách 1:
USES_CONVERSION;
ach1 = A2W (ch);
Cách 2:
size_t convertedChars = 0 ;
/ / record returns the actual length of the string conversion
mbstowcs_s (& convertedChars, ach1, 10, ch, _TRUNCATE) ;
/ / 10 is the maximum length of ch

Degrees, as needs change

10. Chuyển đổi từu int sang string
string str;
int nNumber = 10001;
char cT [10] ;/ / put int into a string
_itoa_s (nNumber, cT, 10);
str = cT; or string str (cT);

11. Chuyển đổi từ string sang int

12.Chuyển đổi từ CString sang char *
Cách 1:
char * ch;
CString temp;
ch = T2A (temp.GetBuffer (0));
Cách 2:
Using casts
CString theString ("This is a test");
LPTSTR lpsz = (LPTSTR) (LPCTSTR) theString;

13. Chuyển đổi từ char * sang CString
Cách 1:
Can directly assign
CString cstr;
char * ch;
cstr = ch;
Cách 2: Bằng cách sử dụng hàm format

char chArray [] = "This is a test";
CString cstr;
MBCS lower (ie not defined UNICODE time):
cstr.Format (_T ("% s"), chArray);
UNICODE is defined:
USES_CONVERSION;
cstr.Format (_T ("% s"), A2W (chArray));

14. Chuyển đổi từ char * sang int
char * ch;
int n = atoi (ch);

15. Chuyển đổi int sang char *
int n = 45;
char nCh [10];
char * ch;
itoa (n, nCh, 16) ;/ / 16 is hexadecimal, 2,8,10,16, also may take the following forms may be used: ch = itoa (n, nCh, 16);
VS2005 atmospheres: _itoa_s (n, nCh, 2);

16. Chuyển CString sang string
string str;
CString temp;
USES_CONVERSION;
str = T2A (temp.GetBuffer (0));

17. Chuyển string sang CString
CString cstr;
string str;
cstr = str.c_str ();

18. Chuyển char * sang string
Phương pháp xây dựng trực tiếp:
char cT1 [20];
string ste (cT1) ;/ / re-construct a string - Xây dựng lại chuỗi

19. Chuyển string sang char *
string ste;
ch = (char *) ste.c_str ();
By removing const char * conversion properties can only pay attention to ch

char *, not to char []

20. Chuyển từ float (hoặc double) sang string
char cT1 [20];
_gcvt_s  (cT1, 20,110.58485678,6) ;/ / 6  số sau dấu thập phân
string ste (cT1);

21. Chuyển string sang double
string num = "15.12054";
double d = atof (num.c_str ());

Chủ Nhật, 2 tháng 6, 2013

Loại bỏ toàn bộ thực thể Proxy trong bản vẽ bằng ObjectARX

Đặt vấn đề
Nếu không có ứng dụng liên quan, làm thể nào để làm việc với bản vẽ có chứa nhiều thực thể proxy (custom entities). Hay làm thế nào để sử dụng dữ liệu trong bản vẽ, như là để xây dựng đối tượng hình học mới. Một vài thực thể có thể explode, nhưng một số khác lại không giống như không thể xóa được chúng vậy. Dù có được các thực thể AutoCAD tương đương nhưng những thực thể proxy vẫn còn đó. Cần phải làm gì?
Giải pháp
Hoàn toàn có thể dùng ObjectARX để chuyển mọi thực thể proxy thành bất cứ cái gì. Ví dụ sau sẽ lặp lại qua bản vẽ và đổi tất cả thực thể Proxy thành một block vo danh. Các block đó chưa đựng các thành phần đồ họa tương đương với thực thể Proxy. Lưu ý rằng việc làm đó không cho phép bạn tạo ra các thực thể mới để lấy được thông tin lưu giữ trong thực thể gốc.
AcDbObjectIdArray proxies;  

// Iterate through the records  
// Make a list of all the proxies, and then process them afterwards. 
AcDbBlockTable* pTable; 
acdbHostApplicationServices()->workingDatabase()->getBlockTable
                                                    (
                                                        pTable,
                                                        AcDb::kForRead
                                                    );
if(pTable == NULL)
    return

AcDbBlockTableIterator* pTableIter;
for( pTable->newIterator(pTableIter); !pTableIter->done(); pTableIter->step())
{     
    AcDbBlockTableRecord* pRecord;     
    pTableIter->getRecord(pRecord,AcDb::kForRead);  
    if(pRecord == NULL)
    {   
        acutPrintf(_T("\nCannot open a BTR"));  
        continue;   
    } 

    AcDbBlockTableRecordIterator* pRecordIter;
    for (    pRecord->newIterator(pRecordIter);
            ! pRecordIter->done();
            pRecordIter->step()
        )
    {
        AcDbEntity*pEnt;    
        pRecordIter->getEntity(pEnt, AcDb::kForRead);
        if(pEnt != NULL )
        {
            if( pEnt->isKindOf(AcDbProxyEntity::desc()))
            {        
                proxies.append(pEnt->objectId() );   
            }          
            pEnt->close();    
        }    
    }   
    delete pRecordIter;   
    pRecord->close(); 
}  

delete pTableIter;
if( Acad::eOk != pTable->upgradeOpen())
{   
    acutPrintf(_T("\nCannot open table for Write"));
    pTable->close();
    return;
}
int nProxies = proxies.length(); 
for( int i=0;i<nProxies; i++ )
    AcDbProxyEntity* pProxy;  
    AcDbObject* pObj;   
    acdbOpenAcDbObject(pObj, proxies[i], AcDb::kForRead);
    pProxy = AcDbProxyEntity::cast(pObj); 
    if( NULL == pProxy )
    {   
        pObj->close () ;  
        continue
    }    
    AcDbVoidPtrArray explodedEnts; 
    pProxy->explode(explodedEnts);
    int nExplodedEnts = explodedEnts.length();
    if( nExplodedEnts > 0 )
    {       
        AcDbBlockTableRecord*pRecord = new AcDbBlockTableRecord();
        pRecord->setName(_T("*B")); 
        AcDbObjectId blockId;   
        pTable->add(blockId, pRecord ); 
        for( int j=0; j<nExplodedEnts; j++)
        {        
            AcDbEntity*pEnt =(AcDbEntity*)(explodedEnts[j]);
            pRecord->appendAcDbEntity(pEnt);
            pEnt->setColorIndex(0);     
            pEnt->close();       
        }      
        pRecord->close(); 
        AcDbBlockTableRecord* pOwningRecord; 
        acdbOpenObject    (   
                            pOwningRecord,
                            pProxy->ownerId(),
                            AcDb::kForWrite
                        ); 
        if( NULL != pOwningRecord)
        {   
            AcDbBlockReference* pRef = new AcDbBlockReference; 
            pRef->setBlockTableRecord(blockId);      
            pOwningRecord->close();       
            pProxy->upgradeOpen();         
            pProxy->handOverTo(pRef); 
            pRef->setColor(pProxy->color()); 
            pRef->setLayer(pProxy->layerId()); 
            pRef->setVisibility(pProxy->visibility());
            delete pProxy;      
            pRef->close();       
        }     
    }     
    else
    { 
        pProxy->close();
    }  
}
pTable->close();


Link nguồn: Adndevblog

Thứ Bảy, 1 tháng 6, 2013

Lấy thông tin từ thực thể proxy (Getting proxy entity’s information)

Làm thế nào để lấy được thông tin của thực thể proxy?

Bạn có thể sử dụng lớp “AcDbProxyEntity” để lấy tên gốc (original name), tên dxf gốc (original dxf name) và số lượng tham chiếu của thực thể proxy (particular entity’s proxy) trong bản vẽ.
Đoạn mã dưới đây trình bày hàm để lấy tên gốc và tên dxf gốc của thực thể proxy.
int nReturn ;
ads_name name;
ads_point pt;

nReturn = acedEntSel(_T("Select proxy entity\n"), name, pt);

if (nReturn != RTNORM)
return;

//Lấy ObjectId của thực thể
AcDbObjectId Id;
if(acdbGetObjectId(Id, name) != Acad::eOk)
return;

//Mở thực thể được chọn
AcDbObject *pObject = NULL;
if(acdbOpenAcDbObject(pObject, Id, AcDb::kForRead) != Acad::eOk)
{
    return;
}

AcDbProxyEntity *pProxy = AcDbProxyEntity::cast(pObject);

if(pProxy != NULL)
{
    acutPrintf(_T("Original class name : %s\n"), pProxy->originalClassName());

    acutPrintf(_T("DXF name : %s\n"), pProxy->originalDxfName());

    acutPrintf(_T("Description : %s\n"), pProxy->applicationDescription());
}

pObject->close();
File Arx: Lệnh GPI hoặc hàm defun (lh_getproxyinform ent)
Download tại Mediafire

Ngoài ra, theo Zatopek từ diễn đàn AutoDesk có 02 cách để lấy được dữ liệu hình học của thực thể trong Proxy.
Trước tiên, bạn cần lấy được AcDbProxyEntity, từ đó dùng hàm getGeomExtens, và bạn có thể phá vỡ nó (nếu cho phép).
Hàm getGeomExtents:
Hàm này điền vào trong mở rộng (extent) với những mở rộng gần đúng. Nếu proxy có đồ họa được ghi lại, từ đó chúng được dùng để tính toán extent. Nếu proxy chỉ có đường bao thì mở rộng cũng chỉ là đường bao hộp mà thôi.
Phá vỡ Explode:
Hàm này tạo ra bản sao của tất cả đối tượng đồ họa nguyên thủy lưu giữ trong proxy và thêm con trỏ tới những thực thể mới tạo ra vào trong mảng thực thể entitySet. Hàm trả về Acad::eOk nếu thành công, ngược lại là Acad::eCannotExplodeEntity (không thể explode).

Hãy xem thêm các giải pháp bên trong:
[Arx path]\samples\database\ARXDBG\Inc\ArxDbgWorldDraw.h
[Arx path]\samples\database\ARXDBG\Tests\ArxDbgWorldDraw.cpp
[Arx path]\samples\database\ARXDBG\Inc\ArxDbgViewportDraw.h
[Arx path]\samples\database\ARXDBG\Tests\ArxDbgViewportDraw.cpp
Arx path là thư mục cài đặt bộ ObjectARX SDK.
 
Link tham khảo:
http://adndevblog.typepad.com
http://forums.autodesk.com

Thư viện AutoLISP mở rộng Doslib (Phần 2)

Các hàm thiết lập -------------------------------------------------------------------------------- dos_getini Trả về giá trị từ tệp tin INI ...