Сообщество программистов Autodesk в СНГ

ADN Club => AutoCAD .NET API => Тема начата: Дмитрий Загорулькин от 17-02-2014, 14:46:37

Название: Создание нового чертежа программным способом.
Отправлено: Дмитрий Загорулькин от 17-02-2014, 14:46:37
Здравствуйте! Создаю программно чертеж таким способом:
Код - C# [Выбрать]
  1. [CommandMethod("NewDBTest")]
  2.         public void NewDBTest()
  3.         {
  4.             Database newDB = new Database(true, false);
  5.             newDB.SaveAs(@"D:\Test.dwg", DwgVersion.Current);
  6.         }
  7.  

При этом, совершенно непонятно, на основе какого шаблона (и по шаблону ли?) создается новый чертеж. Я предполагал, что шаблон берется из настроек по умолчанию для создания новых чертежей, но практика показала, что это не так. Как минимум, не совпадают единицы чертежа. Так что же берется за основу при создании чертежа по этому способу?
Название: Re: Создание нового чертежа программным способом.
Отправлено: Андрей Бушман от 17-02-2014, 14:54:44
https://sites.google.com/site/bushmansnetlaboratory/translate-manual/upravlenie-sredoj-autocad/sozdanie-otkrytie-sohranenie-i-zakrytie-certezej/sozdanie-i-otkrytie-certeza
Название: Re: Создание нового чертежа программным способом.
Отправлено: Александр Ривилис от 17-02-2014, 15:13:47
Так что же берется за основу при создании чертежа по этому способу?
Ничего. Создается пустая база с настройка по-умолчанию для базы (никак не связанная ни с какими шаблонами).
Если хочешь создавать по шаблону можно воспользоваться одним из вариантов:
1) проще всего скопировать файл шаблона в файл с именем будущего чертежа.
2) Можно еще воспользоваться методом DocumentCollection.Add, но при этом будет создан документ, а не база.
3) Открыть файл шаблона как Database и для неё сделать Wblock (без параметров) в новую базу.
Название: Re: Создание нового чертежа программным способом.
Отправлено: Александр Ривилис от 17-02-2014, 15:24:06
А еще можешь попробовать 4-ый метод:
Код - C# [Выбрать]
  1.     [CommandMethod("NewDBTest")]
  2.     public void NewDBTest()
  3.     {
  4.          Database newDB = new Database(false, true);
  5.          // Считываем файл шаблона
  6.          newDB.ReadDwgFile(@"D:\MyTemplate.dwt", FileOpenMode.OpenForReadAndWriteNoShare, true, "");
  7.          // Для того чтобы быть уверенным что весь шаблон прочитался
  8.          newDB.closeInput(true);
  9.          newDB.SaveAs(@"D:\Test.dwg", DwgVersion.Current);
  10.     }
     
Название: Re: Создание нового чертежа программным способом.
Отправлено: Дмитрий Загорулькин от 17-02-2014, 15:38:26
Спасибо, понял.
В идеале, хотелось бы создать копию существующего чертежа, но без примитивов. А потом перенести в нее только нужные примитивы. Но цивилизованного способа для такого я не придумал, поэтому создание нового чертежа по шаблону - наиболее приемлемая альтернатива.
4-й метод мне очень нравится! Буду пробовать его применять.
Название: Re: Создание нового чертежа программным способом.
Отправлено: Александр Ривилис от 17-02-2014, 15:50:27
В идеале, хотелось бы создать копию существующего чертежа, но без примитивов. А потом перенести в нее только нужные примитивы. Но цивилизованного способа для такого я не придумал,
А в чем проблема? Database.Wblock в новую базу и удаляешь все примитивы из неё. Тоже вариант.
Название: Re: Создание нового чертежа программным способом.
Отправлено: Андрей Бушман от 17-02-2014, 15:50:31
Не успел... :) Ну да ладно, всё равно напишу уж, зря, что ли царапал...
Код - C# [Выбрать]
  1. // AutoCAD 2009
  2. // DatabaseUtilites.cs
  3.  
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Text;
  8.  
  9. using cad = Autodesk.AutoCAD.ApplicationServices.Application;
  10. using App = Autodesk.AutoCAD.ApplicationServices;
  11. using Db = Autodesk.AutoCAD.DatabaseServices;
  12. using Ed = Autodesk.AutoCAD.EditorInput;
  13. using Rtm = Autodesk.AutoCAD.Runtime;
  14.  
  15. namespace Bushman.CAD.Utilites {
  16.         public static class DatabaseUtilites {
  17.                 /// <summary>
  18.                 /// Создание базы данных чертежа на основании нужного шаблона (DWT-файла)
  19.                 /// </summary>
  20.                 /// <param name="templateName">Наименование файла шаблона</param>
  21.                 /// <param name="password">Пароль для успешного открытия шаблона. Если пароля нет,
  22.                 /// то следует указывать либо null, либо "".</param>
  23.                 /// <returns>В случае успешного создания возвращается объект Database, иначе - null.</returns>
  24.                 public static Db.Database CreateDatabaseFromTemplate(String templateName, String password) {
  25.                         if (templateName == null || templateName.Trim() == String.Empty) return null;
  26.                         Db.Database templateDb = new Db.Database(false, true);
  27.                         if (password == null) password = String.Empty;
  28.                         templateDb.ReadDwgFile(Environment.ExpandEnvironmentVariables(templateName),
  29.                                 Db.FileOpenMode.OpenForReadAndWriteNoShare, true, password);
  30.                         templateDb.CloseInput(true);
  31.                         Db.Database result = templateDb.Wblock();
  32.                         return result;
  33.                 }
  34.         }
  35. }
Пример использования:
Код - C# [Выбрать]
  1. Db.Database db2 = Bushman.CAD.Utilites.DatabaseUtilites.CreateDatabaseFromTemplate(
  2.         @"%ProgramFiles%\GPSM\AdminCAD\Common\Templates\DWT\Формы по ГОСТ 21.1101-2009.dwt", null);
  3. db2.SaveAs(@"C:\test\123.dwg", Db.DwgVersion.Current);
Название: Re: Создание нового чертежа программным способом.
Отправлено: Дмитрий Загорулькин от 17-02-2014, 15:55:56
А в чем проблема? Database.Wblock в новую базу и удаляешь все примитивы из неё.
Мне кажется, что это нецивилизованный способ. Если чертеж большой, то много лишней работы нужно будет проделать. К тому же, это чертеж, выполненный в вертикальном решении, перетащится еще куча вспомогательных ненужных данных, вычищать придется долго и кропотливо. А вариант с шаблоном мне все больше и больше нравится - в него можно вносить нужные изменения не затрагивая кода.
Название: Re: Создание нового чертежа программным способом.
Отправлено: Андрей Бушман от 17-02-2014, 15:56:32
В идеале, хотелось бы создать копию существующего чертежа, но без примитивов.
А не проще тогда в чистую базу данных (new Db.Database(false, true);) банально импортировать все нужные тебе стили, слои и определения блоков?
Название: Re: Создание нового чертежа программным способом.
Отправлено: Александр Ривилис от 17-02-2014, 15:59:18
Вариант с шаблоном мне все больше и больше нравится - в него можно вносить нужные изменения не затрагивая кода.
Если это устоявшийся шаблон - то ты прав. А если сценарий такой: дают чертеж и на основе его нужно сделать шаблон без примитивов - только установленные системные переменные, таблицы слоев, блоков, типов линий и т.д., то вполне себе нормальное решение.
Название: Re: Создание нового чертежа программным способом.
Отправлено: Андрей Бушман от 17-02-2014, 16:01:30
то вполне себе нормальное решение.
чем лучше обозначенного в #8?
Название: Re: Создание нового чертежа программным способом.
Отправлено: Александр Ривилис от 17-02-2014, 16:06:41
чем лучше обозначенного в #8?
В твоём варианте нужно:
1) Пройтись по списку системных переменных, хранящихся в базе и скопировать их в новую базу
2) Пройтись по всем стилям (слои, блоки, типы линий, текстовые стили ...), NOD и скопировать их.
Кода будет явно больше, нужно будет учесть все возможные варианты, и не думаю, что он будет быстрее.
Название: Re: Создание нового чертежа программным способом.
Отправлено: Андрей Бушман от 17-02-2014, 16:09:18
Кода будет явно больше, нужно будет учесть все возможные варианты, и не думаю, что он будет быстрее.
А вы предлагаете выполнить общую итерацию, в которой удаляются все Entity?
Название: Re: Создание нового чертежа программным способом.
Отправлено: Александр Ривилис от 17-02-2014, 16:12:36
А вы предлагаете выполнить общую итерацию, в которой удаляются все Entity?
Тут тоже возможны варианты. Возможно не нужны примитивы только в ModelSpace, а блоки и примитивы на листах (например рамки и штампы) как раз нужны. Так что всё зависит от постановки задачи.
Название: Re: Создание нового чертежа программным способом.
Отправлено: Андрей Бушман от 17-02-2014, 16:20:52
Если удалять всё одним махом:
Код - C# [Выбрать]
  1. Db.Database db = cad.DocumentManager.MdiActiveDocument.Database;
  2. using (Db.Transaction tr = db.TransactionManager.StartTransaction()) {
  3.         for (Int64 i = db.BlockTableId.Handle.Value; i < db.Handseed.Value; i++) {
  4.                 Db.ObjectId id = Db.ObjectId.Null;
  5.                 Db.Handle h = new Db.Handle(i);
  6.                 if (db.TryGetObjectId(h, out id) && id != Db.ObjectId.Null && id.IsValid) {
  7.                         Db.Entity x = tr.GetObject(id, Db.OpenMode.ForWrite) as Db.Entity;
  8.                         if (x != null) x.Erase(true);
  9.                 }
  10.         }
  11.         tr.Commit();
  12. }
то могут ли возникнуть такие ситуации, что удалить один объект мы не сможем, пока не будут предварительно удалены некоторые др. объекты, зависящие от него? Т.е. важен ли порядок удаления, или же зависимые будут удаляться автоматом?
Название: Re: Создание нового чертежа программным способом.
Отправлено: Александр Ривилис от 17-02-2014, 16:25:45
то могут ли возникнуть такие ситуации, что удалить один объект мы не сможем, пока не будут предварительно удалены некоторые др. объекты, зависящие от него? Т.е. важен ли порядок удаления?
Тут проблем быть не должно. Но! Таким образом ты удалишь все примитивы внутри блоков. Т.е блоки окажутся пустыми.
Название: Re: Создание нового чертежа программным способом.
Отправлено: Дмитрий Загорулькин от 17-02-2014, 16:27:06
А еще можешь попробовать 4-ый метод:
Все, проверил, прекрасно работает! Хочу заметить, что в методе Database.ReadDwgFile нужно указывать полный путь к шаблону, файл в путях поддержки сам не ищется. Хотя, возможно, что это нормально для NET.
Другие способы, про которые вы писали в этой теме, гораздо более трудоемки и не факт, что дадут нужный результат. С шаблоном же всегда можно оперативнее подстроиться под желания пользователей.
Еще раз спасибо за советы!
Название: Re: Создание нового чертежа программным способом.
Отправлено: Андрей Бушман от 17-02-2014, 16:27:45
Тут проблем быть не должно. Но! Таким образом ты удалишь все примитивы внутри блоков. Т.е блоки окажутся пустыми.
А, ну да... :) Нужно выполнять итерацию по модели и листам.
Название: Re: Создание нового чертежа программным способом.
Отправлено: Александр Ривилис от 17-02-2014, 16:28:53
Все, проверил, прекрасно работает!
Отлично!
Хочу заметить, что в методе Database.ReadDwgFile нужно указывать полный путь к шаблону, файл в путях поддержки сам не ищется. Хотя, возможно, что это нормально для NET.
Это вообще нормально. :)
Название: Re: Создание нового чертежа программным способом.
Отправлено: Андрей Бушман от 17-02-2014, 16:33:29
файл в путях поддержки сам не ищется
Как вариант (https://sites.google.com/site/bushmansnetlaboratory/moi-zametki/rabota-s-katalogami-poiska).
Название: Re: Создание нового чертежа программным способом.
Отправлено: Дмитрий Загорулькин от 20-02-2014, 19:43:57
Ничего. Создается пустая база с настройка по-умолчанию для базы (никак не связанная ни с какими шаблонами).
Похоже, что метод Database.Wblock точно так же новый чертеж создает. Вытаскиваю объекты из чертежа этим методом. В результате, в новом чертеже совершенно другие единицы. В исходном метры, в получаемом - футы. Можно как-то эти настройки по умолчанию переопределять?

Update:
А, я там новую базу данных так же создаю: new Database(true, false). Понятно, почему "все по умолчанию".
Название: Re: Создание нового чертежа программным способом.
Отправлено: Александр Ривилис от 21-02-2014, 01:19:27
А, я там новую базу данных так же создаю: new Database(true, false). Понятно, почему "все по умолчанию".
Разобрался? Теперь всё нормально?
Название: Re: Создание нового чертежа программным способом.
Отправлено: Дмитрий Загорулькин от 21-02-2014, 10:01:49
Да, я разобрался, почему так происходит. А вот как с этим бороться - пока неясно. Наверное, тоже придется указывать конкретный шаблон для создания нового чертежа.
Название: Re: Создание нового чертежа программным способом.
Отправлено: Александр Ривилис от 21-02-2014, 20:28:54
Database.Wblock (если использовать метод без параметров) создаёт новую базу с теми же параметрами, что и у базы, для которой этот метод выполняется. Так что единицы измерения должны быть одинаковы. Во всяком случае в чистом AutoCAD - Civil3D возможно обрабатывает единицы посвоему.
Название: Re: Создание нового чертежа программным способом.
Отправлено: Дмитрий Загорулькин от 24-02-2014, 13:45:20
Да, этот вариант работает! Но, в новую БД копируются все объекты исходной БД, примитивы в том числе. По сути, создается полная копия исходного чертежа. Мне такое не подходит.
В общем, сделал тоже с использованием шаблона - хорошо работает, все устраивает.
Название: Re: Создание нового чертежа программным способом.
Отправлено: Дмитрий Загорулькин от 25-03-2014, 17:20:16
Хорошо работало и устраивало...
Возникли проблемы с аннотативными объектами. В исходном чертеже их видно, в получаемом - нет. Манипуляции с переменными не спасают.
Видимо, нужно еще дополнительно перетаскивать какие-то настройки чертежа, касающиеся аннотативности.
Название: Re: Создание нового чертежа программным способом.
Отправлено: Андрей Бушман от 25-03-2014, 17:22:46
имеешь в виду, что у объектов, полученных с помощью wblock, слетает список их аннотативных масштабов?
Название: Re: Создание нового чертежа программным способом.
Отправлено: Александр Ривилис от 25-03-2014, 17:28:10
На всякий случай напоминаю, что масштабы аннотаций содержаться в словаре ACAD_SCALELIST:
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fimg845.imageshack.us%2Fimg845%2F8818%2Fhcw1.png&hash=86155f61a8c68959b3ee725f34d7bbfb)

Название: Re: Создание нового чертежа программным способом.
Отправлено: Дмитрий Загорулькин от 25-03-2014, 19:56:21
Подумав, решил создавать полную копию чертежа и вычищать примитивы. Мало ли что потом еще вылезет...
Название: Re: Создание нового чертежа программным способом.
Отправлено: Александр Ривилис от 25-03-2014, 21:12:59
Подумав, решил создавать полную копию чертежа и вычищать примитивы. Мало ли что потом еще вылезет...
:D А ведь я советовал именно это сделать сразу!
Название: Re: Создание нового чертежа программным способом.
Отправлено: Дмитрий Загорулькин от 26-03-2014, 10:30:47
Это-то да, но по таким соблазнительным граблям было грех не пройтись :)