嵌入和封装对象
有两种方法可以将对象嵌入到另一个对象中:封装对象具有实际嵌入对象的数据成员,或者封装对象具有指向对象的指针(在这种情况下,该对象被视为嵌入对象)。无论哪种情况,封装对象都负责分配和解除分配嵌入对象。封装对象还必须将对嵌入对象方法的所有调用转发,因为 AutoCAD 无法识别嵌入对象。为了显示嵌入对象,封装对象必须调用嵌入对象的 .subWorldDraw()worldDraw() 对于 subG 和 ,必须将嵌入对象的 和 方法称为 last,以便其点的索引高于封装实体的索引。然后,如果传入的任何索引高于封装实体的索引范围,则减去封装实体的最高索引值,并将结果传递到嵌入对象的 或 中。例如,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() 对于 DWG 归档,对嵌入对象和方法的调用可以发生在封装对象的相应方法中的任意点(在调用基类的方法之后)。但是,调用必须发生在 和 的同一位置。以下代码来自更新的 jblob 示例程序: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); } 对于 DXF 归档,必须在封装对象的所有数据都归档和归入后,将嵌入对象归档和归入;因此,对嵌入对象和方法的调用应排在封装对象和方法的最后。封装对象的数据和后续嵌入对象的数据之间需要一个分隔符。分隔符的功能必须与组 0 或 100 相似,因为它必须使文件管理器停止读取数据。不能使用正常的 DXF 组代码 0,因为 DXF 代理使用它来确定何时停止读取数据。可以使用组代码 100,但在手动读取 DXF 文件时可能会造成混淆,并且需要区分何时要写出嵌入对象以进行一些内部簿记。因此,引入了DXF组代码101。dxfOutFields()dxfInFields()dxfOutFields()dxfInFields() DXF 组代码 101 的枚举值为 。数据字符串由文件管理器写出此 DXF 组代码。AcDb::DxfCodeAcDb::kDxfEmbeddedObjectStartEmbedded Object 该类还添加了两种方法:AcDbDxfFiler
以下代码演示了如何在更新的 jblob 示例程序中使用这些方法: 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); } 以下示例显示了 DXF 文件中的输出(为了便于阅读,缩短了 310 组数据字符串): 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 父主题: |
|Archiver|CAD开发者社区
( 苏ICP备2022047690号-1 苏公网安备32011402011833)
GMT+8, 2025-3-28 16:47
Powered by Discuz! X3.4
Copyright © 2001-2021, Tencent Cloud.