Программный импорт блока в AutoCAD (C#)

Я пишу плагин для AutoCAD и хочу импортировать все блоки, которые он будет использовать в начале, чтобы убедиться, что они доступны, когда это необходимо. Для этого я использую этот метод

public static void ImportBlocks(string[] filesToTryToImport, string filter = "")
{
    foreach (string blockToImport in filesToTryToImport)
    {
        if (blockToImport.Contains(filter))
        {
            Database sourceDb = new Database(false, true); //Temporary database to hold data for block we want to import
            try
            {
                sourceDb.ReadDwgFile(blockToImport, System.IO.FileShare.Read, true, ""); //Read the DWG into a side database
                ObjectIdCollection blockIds = new ObjectIdCollection(); // Create a variable to store the list of block identifiers

                Autodesk.AutoCAD.DatabaseServices.TransactionManager tm = sourceDb.TransactionManager;

                using (Transaction myT = tm.StartTransaction())
                {
                    // Open the block table
                    BlockTable bt = (BlockTable)tm.GetObject(sourceDb.BlockTableId, OpenMode.ForRead, false);

                    // Check each block in the block table
                    foreach (ObjectId btrId in bt)
                    {
                        BlockTableRecord btr = (BlockTableRecord)tm.GetObject(btrId, OpenMode.ForRead, false);
                        // Only add named & non-layout blocks to the copy list
                        if (!btr.IsAnonymous && !btr.IsLayout)
                        {
                            blockIds.Add(btrId);
                        }
                        btr.Dispose();
                    }
                }
                // Copy blocks from source to destination database
                IdMapping mapping = new IdMapping();
                sourceDb.WblockCloneObjects(blockIds, _database.BlockTableId, mapping, DuplicateRecordCloning.Replace, false);
                _editor.WriteMessage("\nCopied " + blockIds.Count.ToString() + " block definitions from " + blockToImport + " to the current drawing.");
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                _editor.WriteMessage("\nError during copy: " + ex.Message);
            }
            finally
            {
                sourceDb.Dispose();
            }
        }
    }
}

Этот метод работает, потому что он успешно выполняется. Однако, когда я вставляю блок в чертеж через интерфейс AutoCAD, он не отображается как вариант, а когда я пытаюсь вставить его программно, возникает исключение FileNotFound, означающее, что он не работает. Что не так с этим методом? Заранее спасибо!

РЕДАКТИРОВАТЬ: вот менее сложный метод с тестовым методом

public static void ImportSingleBlock(string fileToTryToImport)
{
    using (Transaction tr = _database.TransactionManager.StartTransaction())
    {
        Database sourceDb = new Database(false, true); //Temporary database to hold data for block we want to import
        try
        {
            sourceDb.ReadDwgFile(fileToTryToImport, System.IO.FileShare.Read, true, ""); //Read the DWG into a side database
            _database.Insert(fileToTryToImport, sourceDb, false);
            _editor.WriteMessage("\nSUCCESS: " + fileToTryToImport);
        }
        catch (Autodesk.AutoCAD.Runtime.Exception ex)
        {
            _editor.WriteMessage("\nERROR: " + fileToTryToImport);
        }
        finally
        {
            sourceDb.Dispose();
        }
        tr.Commit();
    }
}

[CommandMethod("TESTSINGLEBLOCKIMPORTING")]
public void TestSingleBlockImporting()
{
    OpenFileDialog ofd = new OpenFileDialog();
    DialogResult result = ofd.ShowDialog();
    if (result == DialogResult.Cancel) //Ending method on cancel
    {
        return;
    }
    string fileToTryToImport = ofd.FileName;
    using (Transaction tr = _database.TransactionManager.StartTransaction())
    {
        EntityMethods.ImportSingleBlock(fileToTryToImport);
        tr.Commit();
    }
}

Этот файл — блок, который я пытаюсь импортировать. Надеюсь, это вдохновит кого-то, потому что я отчаянно потерян прямо сейчас.


person Nick Gilbert    schedule 11.08.2015    source источник


Ответы (1)


Ваш код правильный и должен работать. На самом деле я пробовал и работает нормально. Возможно, вам не хватает Commit() для внешней транзакции (где вы вызываете этот метод ImportBlocs()). Проверять:

using (Transaction trans = _database.TransactionManager.StartTransaction())
{
  ImportBlocks(... parameters here ...);
  trans.Commit(); // remember to call this commit, if omitted, Abort() is assumed
}
person Augusto Goncalves    schedule 11.08.2015
comment
Мне это не помогло... вот блок, который я пытаюсь импортировать, возможно, проблема в блоке drive.google.com/file/d/0BwwMHXVXHuDjaVZ4NUlNbHNUN0E/ - person Nick Gilbert; 11.08.2015
comment
ах хорошо, этот рисунок является блоком (и не содержит блока). Ваш исходный код читает весь блок, но ваш рисунок не содержит ни одного. Для подобных чертежей следует вызывать Database.Insert(), передавая путь .dwg, который возвращает ObjectId нового определения блока, который затем можно использовать для создания BlockReference. - person Augusto Goncalves; 12.08.2015