CAD开发者社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

ObjectARX 开发指南

嵌入和封装对象

2023-1-1 05:00| 发布者: admin| 查看: 511| 评论: 0|来自: AutoCAD

有两种方法可以将一个对象嵌入到另一个对象中:封装对象具有实际嵌入对象的数据成员,或者封装对象具有指向对象的指针(在这种情况下,该对象被视为嵌入)。在任一情况下,封装对象负责分配和解除分配嵌入对象。封装对象还必须将所有调用转发到嵌入对象的方法,因为 AutoCAD 不知道嵌入对象。为了显示嵌入对象,封装对象必须调用嵌入对象。subWorldDraw()worldDraw()

对于 subGand,您必须最后调用嵌入对象的 sand方法,以便其点最终的索引高于封装实体的索引。然后,如果传入的任何索引高于封装实体的范围,则减去封装实体的最高索引值,并将结果传递到嵌入对象的 sor 中。例如,来自 jblob示例版本的以下代码已更新为具有嵌入式实体:etGripPoints()subGetStretchPoints()getGripPoints()getStretchPoints()subMoveGripPointsAt()subMoveStretchPointsAt()moveGripPointsAt()moveStretchPointsAt()AcDbCircle

Acad::ErrorStatus
Jblob::subGetGripPoints(
    AcGePoint3dArray& gripPoints,
    AcDbIntArray& osnapMasks,
    AcDbIntArray& geomIds) const
{
    assertReadEnabled();
    gripPoints.append(mp);
    gripPoints.append(mp + 0.5 * (mpblob - mp));
    gripPoints.append(mpblob);
    AcGeVector3d xoff(mrblob, 0, 0);
    AcGeVector3d yoff(0, mrblob, 0);
    gripPoints.append(mpblob + xoff);
    gripPoints.append(mpblob + yoff);
    gripPoints.append(mpblob - xoff);
    gripPoints.append(mpblob - yoff);
    return circle.getGripPoints(gripPoints, osnapMasks, geomIds);
}
Acad::ErrorStatus
Jblob::subMoveGripPointsAt(
    const AcDbIntArray& indices,
    const AcGeVector3d& offset)
{
    AcGePoint3d oldquad, newquad;
    assertWriteEnabled();
    AcDbIntArray circleIndices;
    for (int i = 0; i < indices.length(); i++) {
        int idx = indices[i];
        switch(idx) {
        case 0:
            mp += offset;
            continue; // stretch begin point
        case 1:
            mp += offset;
            mpblob += offset;
            continue; // move
        case 2:
            mpblob += offset;
            continue; // stretch blob center
        // stretch blob radius:
        //
        case 3:
            oldquad = mpblob + AcGeVector3d(mrblob, 0, 0);
            break;
        case 4:
            oldquad = mpblob + AcGeVector3d(0, mrblob, 0);
            break;
        case 5:
            oldquad = mpblob - AcGeVector3d(mrblob, 0, 0);
            break;
        case 6:
            oldquad = mpblob - AcGeVector3d(0, mrblob, 0);
            break;
        default:
            if (idx > 6)
                circleIndices.append(idx - 7);
            continue;
        }
        newquad = oldquad + offset;
        mrblob = newquad.distanceTo(mpblob);
    }
    if (circleIndices.length() > 0)
        return circle.moveGripPointsAt(circleIndices, offset);
    else
        return Acad::eOk;
}

出于归档目的,封装对象必须从这些方法的自己的版本中调用嵌入对象的,,,和方法。dwgOutFields()dwgInFields()dxfOutFields()dxfInFields()

For DWG filing, the call to the embedded object's and methods can occur at any point in the corresponding methods of the encapsulating object (after the call to the base class's method). However, the call must occur in the same place in both and . The following code is from the updated jblob sample program: dwgOutFields()dwgInFields()dwgOutFields()dwgInFields()

Acad::ErrorStatus
Jblob::dwgInFields(AcDbDwgFiler* filer)
{
    assertWriteEnabled();
    AcDbEntity::dwgInFields(filer);
    filer->readItem(&mp);
    filer->readItem(&mpblob);
    filer->readItem(&mrblob);
    filer->readItem(&mnormal);
    return circle.dwgInFields(filer);
}
Acad::ErrorStatus
Jblob::dwgOutFields(AcDbDwgFiler* filer) const
{
    assertReadEnabled();
    AcDbEntity::dwgOutFields(filer);
    filer->writeItem(mp);
    filer->writeItem(mpblob);
    filer->writeItem(mrblob);
    filer->writeItem(mnormal);
    return circle.dwgOutFields(filer);
}

For DXF filing, the embedded object must be filed out and in after all the data of the encapsulating object has been filed out and in; therefore, the call to the embedded object's and methods should come last in the encapsulating object's and methods. A separator is needed between the encapsulating object's data and the subsequent embedded object's data. The separator must be similar in function to the group 0 or 100 in that it must cause the filer to stop reading data. The normal DXF group code 0 cannot be used because DXF proxies use it to determine when to stop reading data. The group code 100 could have been used, but it might have caused confusion when manually reading a DXF file, and there was a need to distinguish when an embedded object is about to be written out in order to do some internal bookkeeping. Therefore, the DXF group code 101 was introduced. dxfOutFields()dxfInFields()dxfOutFields()dxfInFields()

The enum value for DXF group code 101 is . The data string is written out by the filer for this DXF group code. AcDb::DxfCodeAcDb::kDxfEmbeddedObjectStartEmbedded Object

Two methods were also added to the class: AcDbDxfFiler

  • writeEmbeddedObjectStart
  • atEmbeddedObjectStart

The following code demonstrates how these methods are used in the updated jblob sample program:

Acad::ErrorStatus
Jblob::dxfInFields(AcDbDxfFiler* filer)
{
    assertWriteEnabled();
    struct resbuf rb;
    Acad::ErrorStatus es = AcDbEntity::dxfInFields(filer);
    if (es != Acad::eOk) {
        return es;
    }
    if (!filer->atSubclassData(kClassName)) {
        return Acad::eBadDxfSequence;
    }
    mnormal = AcGeVector3d(0, 0, 1); // set default value:
    while (es == Acad::eOk) {
        if ((es = filer->readItem(&rb)) == Acad::eOk) {
            switch(rb.restype) {
            case AcDb::kDxfXCoord:
                mp.set(rb.resval.rpoint[X], rb.resval.rpoint[Y],
                    rb.resval.rpoint[Z]);
                break;
            case AcDb::kDxfXCoord+1:
                mpblob.set(rb.resval.rpoint[X], rb.resval.rpoint[Y],
                    rb.resval.rpoint[Z]);
                break;
            case AcDb::kDxfReal:
                mrblob = rb.resval.rreal;
                break;
            case AcDb::kDxfNormalX:
                mnormal.set(rb.resval.rpoint[X], rb.resval.rpoint[Y],
                    rb.resval.rpoint[Z]);
            }
        }
    }
    if (filer->atEmbeddedObjectStart())
        return circle.dxfInFields(filer);
    else {
        filer->setError(Acad::eMissingDxfField,
            "missing expected embeddedObject marker");
        return filer->filerStatus();
    }
}
Acad::ErrorStatus
Jblob::dxfOutFields(AcDbDxfFiler* filer) const
{
    assertReadEnabled();
    AcDbEntity::dxfOutFields(filer);
    filer->writeItem(AcDb::kDxfSubclass, kClassName);
    filer->writeItem(AcDb::kDxfXCoord, mp);
    filer->writeItem(AcDb::kDxfXCoord + 1, mpblob);
    filer->writeItem(AcDb::kDxfReal, mrblob);
    if (filer->includesDefaultValues()
        || mnormal != AcGeVector3d(0,0,1))
    {
        filer->writeItem(AcDb::kDxfNormalX, mnormal);
    }
    filer->writeEmbeddedObjectStart();
    return circle.dxfOutFields(filer);
}

The following example shows the output in a DXF file (with the 310 group data strings shortened for readability):

0
JBLOB
  5
52
330
19
100
AcDbEntity
  8
0
 92
      256
310
00010000040000003C0000000600000002000000...
310
000000000000000000000000000000F03F700000...
310
0000
100
Jblob
 10
4.026791
 20
3.172968
 30
0.0
 11
5.916743
 21
5.299622
 31
0.0
 40
1.458724
101
Embedded Object
100
AcDbEntity
100
AcDbCircle
 10
5.916743
 20
5.299622
 30
0.0
 40
0.729362

路过

雷人

握手

鲜花

鸡蛋

最新评论

QQ|Archiver|CAD开发者社区 ( 苏ICP备2022047690号-1 )

GMT+8, 2024-5-19 12:22

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

返回顶部