Добавление элементов в пространство модели правильным способом с помощью API .NET - PullRequest
0 голосов
/ 14 мая 2019

Метод первый

_AcDb.Line oLine = new _AcDb.Line(ptStart, ptEnd);
AddToModelSpace("PLOT", oLine);

Где AddToModelSpace:

public static void AddToModelSpace(string strLayer, _AcDb.Entity oEntity)
{
    _AcAp.Document acDoc = _AcAp.Application.DocumentManager.MdiActiveDocument;
    _AcDb.Database acCurDb = acDoc.Database;
    _AcEd.Editor ed = acDoc.Editor;

    using (_AcDb.BlockTable bt = acCurDb.BlockTableId.GetObject(_AcDb.OpenMode.ForRead) as _AcDb.BlockTable)
    using (_AcDb.BlockTableRecord ms = bt[_AcDb.BlockTableRecord.ModelSpace].GetObject(_AcDb.OpenMode.ForWrite) as _AcDb.BlockTableRecord)
        ms.AppendEntity(oEntity);
    oEntity.Layer = strLayer;
    oEntity.Dispose();
}

Метод второй

// Get the current document and database
_AcAp.Document docActive = _AcAp.Application.DocumentManager.MdiActiveDocument;
_AcDb.Database docDB = docActive.Database;

// Start a transaction
using (_AcDb.Transaction acTrans = docDB.TransactionManager.StartTransaction())
{
    // Open the Block table for read
    _AcDb.BlockTable acBlkTbl;
    acBlkTbl = acTrans.GetObject(docDB.BlockTableId,
                                    _AcDb.OpenMode.ForRead) as _AcDb.BlockTable;

    // Open the Block table record Model space for write
    _AcDb.BlockTableRecord acBlkTblRec;
    acBlkTblRec = acTrans.GetObject(acBlkTbl[_AcDb.BlockTableRecord.ModelSpace],
                                    _AcDb.OpenMode.ForWrite) as _AcDb.BlockTableRecord;

    // Create line
    using (_AcDb.Line acLine = new _AcDb.Line(ptStart, ptEnd))
    {

        // Add the new object to the block table record and the transaction
        acBlkTblRec.AppendEntity(acLine);
        acTrans.AddNewlyCreatedDBObject(acLine, true);
    }

    // Save the new object to the database
    acTrans.Commit();
}

Я использовал AddToModelSpace в своем проекте, такЯ надеюсь, что это хорошо!

1 Ответ

1 голос
/ 15 мая 2019

Второй метод - это то, что Autodesk рекомендует в документации разработчика (вы можете прочитать этот раздел ).

В первом методе вы используете метод ObjectId.GetObject(), чтобы открыть BlockTable и пространство модели 'BlockTableRecord'.Этот метод использует верхнюю транзакцию для открытия объекта, что означает, что есть активная транзакция, которую вы должны использовать для добавления вновь созданной сущности.Вы можете получить это с Database.TransactionManager.TopTransaction.Если вы вообще не хотите использовать транзакцию, вы должны использовать метод «только для расширенного использования» ObjectId.Open().

Метод Три должен использовать некоторые методы расширения, которые будут вызываться изнутрисделка.Вот упрощенный (без проверки ошибок) экстракт тех, которые я использую.

static class ExtensionMethods
{
    public static T GetObject<T>(
        this ObjectId id, 
        OpenMode mode = OpenMode.ForRead,
        bool openErased = false, 
        bool forceOpenOnLockedLayer = false)
        where T : DBObject
    {
        return (T)id.GetObject(mode, openErased, forceOpenOnLockedLayer);
    }

    public static BlockTableRecord GetModelSpace(this Database db, OpenMode mode = OpenMode.ForRead)
    {
        return SymbolUtilityServices.GetBlockModelSpaceId(db).GetObject<BlockTableRecord>(mode);
    }

    public static ObjectId Add (this BlockTableRecord owner, Entity entity)
    {
        var tr = owner.Database.TransactionManager.TopTransaction;
        var id = owner.AppendEntity(entity);
        tr.AddNewlyCreatedDBObject(entity, true);
        return id;
    }
}

Используя пример:

using (var tr = db.TransactionManager.StartTransaction())
{
    var line = new Line(startPt, endPt) { Layer = layerName };
    db.GetModelSpace(OpenMode.ForWrite).Add(line);
    tr.Commit();
}
...