Trang

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

Thứ Năm, 11 tháng 7, 2013

Tạo mới UCS và đặt làm UCS hiện hành

By Gopinath Taget

Đoạn mã nguồn sau đây trình bày cách tạo một UCS đặt tên và thiết lập nó thành UCS hiện hành. Có hai hàm cần phải nhớ là:

  1. acedVports2VportTableRecords() - Hàm này cần được gọi trước khi truy cập đến bảng các viewport.
  2. acedVportTableRecords2Vports() - Hàm này cần được gọi khi kết thúc chương trình để áp dụng các thay đổi lên bảng viewport.
Hai hàm trên rất cần thiết để AutoCAD có thể cập nhật viewport với các thiết lập hiện hành.

// - asdkucsarx._test command (do not rename)
static void asdkucsarx_test(void)
{
Acad::ErrorStatus es;
AcDbUCSTableRecord *myUCS = new AcDbUCSTableRecord;

//define your own ucs

AcGePoint3d origin_point(0,0,0);
AcGeVector3d UCSXaxis(0,1,0);
AcGeVector3d UCSYaxis(1,0,0);

myUCS->setOrigin(origin_point);
myUCS->setXAxis(UCSXaxis);
myUCS->setYAxis(UCSYaxis);

es=myUCS->setName( _T("MyUCS"));

if (es != Acad::eOk)
{
acutPrintf(_T("\nFailed to set name"));
return;
}

AcDbObjectId UCSId;
AcDbSymbolTable *pUCSTable;

if (acdbHostApplicationServices()->workingDatabase()->
getUCSTable(pUCSTable,AcDb::kForWrite)==Acad::eOk)
{
es=pUCSTable->add(UCSId,myUCS);
es=pUCSTable->close();
es= myUCS->close();
}
else
{
acutPrintf(_T("\nFailed to get UCS table"));
return;
}

//To set the current UCS, I accessed
// the active AcDbViewportTableRecord
// and used setUCS to set the UCS I created as current.

AcDbViewportTable *pVT;
es = acedVports2VportTableRecords();
if (es != Acad::eOk)
{
acutPrintf(
_T("\nFailed to load vport info into vport table records"));
return;
}

es=acdbHostApplicationServices()->
workingDatabase()->getViewportTable(pVT,AcDb::kForRead);
if (es != Acad::eOk)
{
acutPrintf(_T("\nFailed to get vport table"));
pVT->close();
return;
}

AcDbViewportTableIterator* pIter = NULL;

es=pVT->newIterator(pIter);

if (es != Acad::eOk)
{
acutPrintf(_T("\nFailed to get vport table"));
pVT->close();
delete pIter;
return;
}

for (pIter->start();!pIter->done();pIter->step())
{

AcDbViewportTableRecord* pRec;
//it should be open for write mode
es=pIter->getRecord(pRec,AcDb::kForWrite);

if (es != Acad::eOk)
{
acutPrintf(
_T("\nFailed to get vport table record"));
pVT->close();
pRec->close();
delete pIter;
return;
}

TCHAR* name=NULL;
es=pRec->getName(name);
if (es != Acad::eOk)
{
acutPrintf(
_T("\nFailed to get name from vport table"));
pVT->close();
pRec->close();
delete pIter;
return;
}

if (_tcsicmp(name,_T("*ACTIVE"))==0)
{
es=pRec->setUcs(UCSId);
}
es=pRec->close();
}
es=acedVportTableRecords2Vports(); //force update
es=pVT->close();
delete pIter;
return ;
}

Tạo Viewports mới trong không gian PaperSpace

By Augusto Goncalves

Để tạo mới một viewport trong không gian PaperSpace, giống như lệnh MVIEW, thực hiện theo các bước sau:
  1. Tạo một đối tượng mới có kiểu AcDbViewport.
  2. Thiết lập tọa độ view (với các hàm setWidth(), setHeight()setCenterPoint()).
  3. Thêm viewport vào không gian paper.
  4. Lấy các thiết lập view từ người dùng (AcDbViewTableRecord).
  5. Thiết lập view có được trong viewport mới tạo ra bằng hàm acdbSetCurrentView().
  6. Kích hoạt viewport với hàm AcDbViewport::setOn().

CHÚ Ý: Hàm AcDbViewport::setOn() chỉ làm việc nếu lệnh của bạn được đăng ký mà không có flag ACRX_CMD_TRANSPARENT. Nếu không, AcDbViewport::setOn() sẽ trả về eCommandWasInProgress và bạn không thể kích hoạt viewport cho đến khi đặt biến TILEMODE bằng 1 rồi trở về 0.  avnd you cannot activate the viewport until you set tilemode to 1 and back to 0.

Dưới đây là mã nguồn thực hiện:

// Only works in paperspace
AcDbObjectId mCurViewportId = acedGetCurViewportObjectId();
if (mCurViewportId == AcDbObjectId::kNull)
{
acutPrintf(_T("\nCommand only works in paperspace."));
return;
}

AcDbViewport *pCurViewport;
if (Acad::eOk != acdbOpenObject(pCurViewport,mCurViewportId,
AcDb::kForRead))
{
acutPrintf(_T("\nCannot get active viewport."));
return;
}

if (pCurViewport->number() != 1)
{
acutPrintf(_T("\nCommand only works in paperspace."));
pCurViewport->close();
return;
}
pCurViewport->close();

// Ask for the position
ads_point pt1,pt2;

if (RTNORM != acedGetPoint(NULL,
_T("\nSelect first corner: "), pt1))
return;

if (RTNORM != acedGetCorner(pt1,
_T("\nSelect second corner: "), pt2))
return;

// Ask for the view to use
ACHAR mViewName[133];

if (RTNORM != acedGetString(0,
_T("\nEnter name of view to use: "), mViewName))
return;

// Create new viewport
AcDbViewport *pViewport = new AcDbViewport;

pViewport->setWidth(fabs(pt2[X] - pt1[X]));
pViewport->setHeight(fabs(pt2[Y] - pt1[Y]));
pViewport->setCenterPoint(AcGePoint3d(
pt1[X] + (pt2[X] - pt1[X]) / 2,
pt1[Y] + (pt2[Y] - pt1[Y]) / 2,
pt1[Z]));

// Append new viewport to paper space
AcDbBlockTable *pTable;
AcDbBlockTableRecord *pPsBTR;

if (Acad::eOk != acdbHostApplicationServices()->
workingDatabase()->getBlockTable(pTable, AcDb::kForRead))
{
acutPrintf(_T("\nCannot get block table."));
delete pViewport;
return;
}

if (Acad::eOk != pTable->getAt(ACDB_PAPER_SPACE, pPsBTR,
AcDb::kForWrite))
{
acutPrintf(_T("\nCannot access paper space."));
pTable->close();
delete pViewport;
return;
}
pTable->close();

AcDbObjectId mViewPortId;
if (Acad::eOk != pPsBTR->appendAcDbEntity(mViewPortId, pViewport))
{
acutPrintf(_T("\nCannot append viewport to paper space."));
pPsBTR->close();
delete pViewport;
return;
}
pPsBTR->close();
pViewport->setOn();

// Set the view
AcDbViewTable *pViewTable;
AcDbViewTableRecord *pViewTR;

if (Acad::eOk != acdbHostApplicationServices()->
workingDatabase()->getViewTable(pViewTable, AcDb::kForRead))
{
acutPrintf(_T("\nCannot get view table."));
pViewport->close();
return;
}

if (Acad::eOk != pViewTable->getAt(mViewName,
pViewTR, AcDb::kForRead))
{
acutPrintf(_T("\nCannot access view '%s'."), mViewName);
pViewport->close();
pViewTable->close();
return;
}

pViewTable->close();

if (acedSetCurrentView(pViewTR, pViewport)!=Acad::eOk)
acutPrintf(_T("\nFailed to set view"));

// Close the objects
pViewTR->close();
pViewport->close();

Thứ Sáu, 7 tháng 6, 2013

Tìm giao cắt giữa hai đối tượng AcDbEntity


Hàm intersectWith()có hai mẫu sau:
virtual  Acad::ErrorStatus
intersectWith(
    const AcDbEntity* ent,
    AcDb::Intersect intType,
    AcGePoint3dArray& points,
    int thisGsMarker = 0,
    int otherGsMarker = 0) const;
  
virtual  Acad::ErrorStatus
intersectWith(
    const AcDbEntity* ent,
    AcDb::Intersect intType,
    const AcGePlane& projPlane,
    AcGePoint3dArray& points,
    int thisGsMarker = 0,
    int otherGsMarker = 0) const;
Cấu trúc đầu tiên của hàm intersectWith () kiểm tra sự giao cắt đơn giản của hai thực thể. Hàm thứ hai tính toán giao điểm trên mặt chiếu. Tuy nhiên, cả hai đều trả về các giao điểm nằm trên chính thực thể.

Để sử dụng mặt chiếu trong hàm intersectWith(),
  1. Chiếu hai thực thể vào trong mặt phẳng.
  1. Kiểm tra các thực thể để tìm giao điểm trên mặt chiếu.
  1. Chiếu hình chiếu giao điểm tìm được trở lại thực thể sẽ được giao điểm cần tìm.
Đối tượng mới AsdkPoly sử dụng cả hai mẫu của hàm  intersectWith().
Acad::ErrorStatus
AsdkPoly::intersectWith(
    const AcDbEntity* ent,
    AcDb::Intersect intType,
    AcGePoint3dArray& points,
    int /*thisGsMarker*/,
    int /*otherGsMarker*/) const
{
    assertReadEnabled();
    Acad::ErrorStatus es = Acad::eOk;
    if (ent == NULL)
        return Acad::eNullEntityPointer;
// Ý tưởng là cắt qua từng cạnh của đa giác với thực thể cho trước
// và trả về tất cả các giao điểm.
//
// Với thực thể không phải R12 (phiên bản cũ của AutoCAD) với phương thức
// giao điểm đã được định nghĩa, chúng ta chỉ cần gọi phương thức đó
// với mỗi cạnh của đa giác.
// Với thực thể R12, từ khi các giao thức không được thực hiện,
// chúng ta sử dụng hàm giao điểm riêng cho từng thực thể.
//

// Kiểm tra thực thể có phải là AcDbLine?
    if (ent->isKindOf(AcDbLine::desc())) {
        if ((es = intLine(this, AcDbLine::cast(ent),
            intType, NULL, points)) != Acad::eOk)
        {
            return es;
        }
    } else if (ent->isKindOf(AcDbArc::desc())) {
        if ((es = intArc(this, AcDbArc::cast(ent), intType,
            NULL, points)) != Acad::eOk)
        {
            return es;
        }
    } else if (ent->isKindOf(AcDbCircle::desc())) {
        if ((es = intCircle(this, AcDbCircle::cast(ent),
            intType, NULL, points)) != Acad::eOk)
        {
            return es;
        }
    } else if (ent->isKindOf(AcDb2dPolyline::desc())) {
        if ((es = intPline(this, AcDb2dPolyline::cast(ent),
            intType, NULL, points)) != Acad::eOk)
        {
            return es;
        }
    } else if (ent->isKindOf(AcDb3dPolyline::desc())) {
        if ((es = intPline(this, AcDb3dPolyline::cast(ent),
            intType, NULL, points)) != Acad::eOk)
        {
            return es;
        }
    } else {
        AcGePoint3dArray vertexArray;
        if ((es = getVertices3d(vertexArray))
            != Acad::eOk)
        {
            return es;
        }
        if (intType == AcDb::kExtendArg
            || intType == AcDb::kExtendBoth)
        {
            intType = AcDb::kExtendThis;
        }
        AcDbLine *pAcadLine;
        for (int i = 0; i < vertexArray.length() - 1; i++) {
            pAcadLine = new AcDbLine();
            pAcadLine->setStartPoint(vertexArray[i]);
            pAcadLine->setEndPoint(vertexArray[i + 1]);
            pAcadLine->setNormal(normal());
            if ((es = ent->intersectWith(pAcadLine, intType,
                points)) != Acad::eOk)
            {
                delete pAcadLine;
                return es;
            }
            delete pAcadLine;
        }
    }
    return es;
}

Acad::ErrorStatus
AsdkPoly::intersectWith(
    const AcDbEntity* ent,
    AcDb::Intersect intType,
    const AcGePlane& projPlane,
    AcGePoint3dArray& points,
    int /*thisGsMarker*/,
    int /*otherGsMarker*/) const
{
    assertReadEnabled();
    Acad::ErrorStatus es = Acad::eOk;
    if (ent == NULL)
// Ý tưởng là cắt qua từng cạnh của đa giác với thực thể cho trước
// và trả về tất cả các giao điểm.
//
// Với thực thể không phải R12 (phiên bản cũ của AutoCAD) với phương thức
// giao điểm đã được định nghĩa, chúng ta chỉ cần gọi phương thức đó
// với mỗi cạnh của đa giác.
// Với thực thể R12, từ khi các giao thức không được thực hiện,
// chúng ta sử dụng hàm giao điểm riêng cho từng thực thể.
//
    if (ent->isKindOf(AcDbLine::desc())) {
        if ((es = intLine(this, AcDbLine::cast(ent),
            intType, &projPlane, points)) != Acad::eOk)
        {
            return es;
        }
    } else if (ent->isKindOf(AcDbArc::desc())) {
        if ((es = intArc(this, AcDbArc::cast(ent), intType,
            &projPlane, points)) != Acad::eOk)
        {
            return es;
        }
    } else if (ent->isKindOf(AcDbCircle::desc())) {
        if ((es = intCircle(this, AcDbCircle::cast(ent),
            intType, &projPlane, points)) != Acad::eOk)
        {
            return es;
        }
    } else if (ent->isKindOf(AcDb2dPolyline::desc())) {
        if ((es = intPline(this, AcDb2dPolyline::cast(ent),
            intType, &projPlane, points)) != Acad::eOk)
        {
            return es;
        }
    } else if (ent->isKindOf(AcDb3dPolyline::desc())) {

        if ((es = intPline(this, AcDb3dPolyline::cast(ent),
            intType, &projPlane, points)) != Acad::eOk)
        {
            return es;
        }
    } else {
        AcGePoint3dArray vertexArray;
        if ((es = getVertices3d(vertexArray))
            != Acad::eOk)
        {
            return es;
        }
        if (intType == AcDb::kExtendArg
            || intType == AcDb::kExtendBoth)
        {
            intType = AcDb::kExtendThis;
        }
        AcDbLine *pAcadLine;
        for (int i = 0; i < vertexArray.length() - 1; i++) {
            pAcadLine = new AcDbLine();
            pAcadLine->setStartPoint(vertexArray[i]);
            pAcadLine->setEndPoint(vertexArray[i + 1]);
            pAcadLine->setNormal(normal());
            if ((es = ent->intersectWith(pAcadLine, intType,
                projPlane, points)) != Acad::eOk)
            {
                delete pAcadLine;
                return es;
            }
            delete pAcadLine;
        }
        // Tất cả các điểm ta chọn trong tiến trình này đều nằm trên đường cong kia;
        // chúng ta gắn nó với giao cắt hiển nhiên. Nếu đường đối tượng kia là 3D hoặc không đồng phẳng
        // như poly, các điểm giao cắt sẽ không nằm trên poly nữa.
        //
        // Trong trường hợp này, chúng ta cần làm thêm một số việc khác.
        // Chiếu giao điểm trở lại mặt phẳng, chúng nằm trên hình chiếu của poly
        // Tìm điểm điểm trên poly thật để lấy các giao điểm tương ứng
        //
        AcGePoint3d projPt, planePt;
        AcGePoint3dArray pts;
        AcGeLine3d line;
       
        AcGePlane polyPlane;
        AcDb::Planarity plnrty;
        getPlane(polyPlane,plnrty);
        for (i = 0; i < points.length(); i++) {
            // Định nghĩa một đường thẳng xuất phát từ mặt phẳng projPt nằm
            // dọc theo vector. Xác định giao cắt của đa giác với đường thẳng đó.
            // Tìm mọi điểm và nhặt điểm một gần nhất..
            //
            projPt = points[i].orthoProject(projPlane);
            line.set(projPt, projPlane.normal());
            if ((es = intLine(this, line, pts))
                != Acad::eOk)
            {
                return es;
            }
            planePt = projPt.project(polyPlane,
                projPlane.normal());
            points[i] = pts[0];
            double length = (planePt - pts[0]).length();
            double length2;
            for (int j = 1; j < pts.length(); j++) {
                if ((length2 = (planePt - pts[j]).length())
                    < length)
                {
                    points[i] = pts[j];
                    length = length2;
                }
            }
        }
    }
    return es;
}


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 ...