0

我有一个用 C++ 编写的应用程序,我必须将它迁移到 C#。此应用程序是 AutoCAD 的扩展。

C++ AutoCAD API 中的 resbuf 是一个链表,它处理所有 AutoCAD 基本数据类型。看起来像这样

struct resbuf {
  struct resbuf * rbnext;
  short restype;
  union ads_u_val resval;
};

因此,每个 resbuf 都包含 restype 成员描述的特定数据。例如,代码为 410 的 restype 是图层名称。所以在 C# 上它看起来像这样

Entity entity; // Get object here
string layer = entity.Layer;

在该应用程序中,resbuf 结构被用作处理 AutoCAD 对象的一种方式,无论我遇到 resbuf,我都会直接使用对象(线、折线、多行文字等)对其进行更改。

但是现在我发现resbuf的用法是代码10,我打开文档发现如下

10:主要点。这是线或文本实体的起点、圆心等。

而且我不知道迁移它的方式。因为对于每个对象,它都是不同的属性。唯一的想法是这样的。

public void ChangePoint(Entity entity, Point3d value)
{
    if (entity is Line)
    {
        // here code for Line
    }
    else if (entity is Circle)
    {
        // here code for Circle
    }
    // And so on
}

但我不喜欢它。可能有更好的方法来做到这一点。你有什么主意吗?

4

2 回答 2

2

第一个 resbuf 是 AutoCAD API 的 ADS 版本,它是一个 C API。ObjectARX 是 AutoCAD API 的 C++ 版本,仍将 resbuf 用于 XData,但不再用于实体属性访问。在 ObjectARX (C++) 和 AutoCAD .Net API (C#/VB.Net) 中,您可以分别使用特定的方法和访问器访问实体属性(参见底部的示例)。

使用DXF 表读取 resbuf 链表中的代码。

其次,代码 DXF 410 只是一个字符串。如果他愿意,有人可以使用它并存储层名称,但实体层由 DXF 代码 8 引用。

最后的 DXF 代码 10,表示实体的第一个有意义的点。这可以是圆的中心,也可以是直线的第一个点,等等...这就是为什么使用 resbuf 需要更多的关注和了解底层 AutoCAD 数据库结构的组织方式,而不是使用访问器。

例如:

广告 (C)

ads_name en ;
ads_point pt ;
acedEntSel ("\nSelect an Entity: ", en, pt) ; // was ads_entsel() long time ago
struct resbuf *res =acdbEntGet (en) ;
// ... do something with res parsing the linked list and search for specific codes
// Entity Layer is code 8
// ... Eventually push changes to the entity using acdbEntMod()

ObjectARX (C++)

ads_name en ;
ads_point pt ;
acedEntSel ("\nSelect an Entity: ", en, pt) ; // was ads_entsel() long time ago
AcDbObjectId id ;
acdbGetObjectId (id, en) ;
AcDbObjectPointer<AcDbEntity> pEnt (id, AcDb::kForWrite) ;
AcDbObjectId layerId =pEnt->layerId () ;
// ... do something with pEnt ...
// Eventually set a new layer
pEnt->setLayer (newLayerId, true) ;

AutoCAD .Net (C#)

Document doc =Application.DocumentManager.MdiActiveDocument ;
Database db =doc.Database ;
Editor ed =doc.Editor ;

PromptSelectionResult psr =ed.GetSelection () ;
SelectionSet ss =psr.Value ;
SelectedObject so =ss [0] ;

Transaction tr =doc.TransactionManager.StartTransaction () ;
Entity ent =tr.GetObject (so.ObjectId, OpenMode.ForWrite) as Entity ;
ObjectId layerId =ent.Layer ;
// ... do something with ent ...
// Eventually set a new layer
ent.Layer =newLayer ;

tr.Commit () ;
// Regen clears highlighting and reflects the new layer
ed.Regen () ;
于 2016-04-11T08:57:54.057 回答
0

我不是 C# 的高手,但对 ARX 有点了解。对我来说,您似乎在您的应用程序中使用了某种 DXF 迭代器。在 C++ 中你可以使用 acdbEntGet 所以在 C# 中你也可以使用它。参见示例:

http://adndevblog.typepad.com/autocad/2012/05/accessing-visible-entities-in-a-dynamic-block.html

我想以类似的方式您可以使用相应的:acdbEntMake acdbEntMod 来创建、修改实体

于 2016-04-12T08:14:57.433 回答