Создание нового чертежа программным способом.

Автор Тема: Создание нового чертежа программным способом.  (Прочитано 16208 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Здравствуйте! Создаю программно чертеж таким способом:
Код - 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.  

При этом, совершенно непонятно, на основе какого шаблона (и по шаблону ли?) создается новый чертеж. Я предполагал, что шаблон берется из настроек по умолчанию для создания новых чертежей, но практика показала, что это не так. Как минимум, не совпадают единицы чертежа. Так что же берется за основу при создании чертежа по этому способу?


Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Так что же берется за основу при создании чертежа по этому способу?
Ничего. Создается пустая база с настройка по-умолчанию для базы (никак не связанная ни с какими шаблонами).
Если хочешь создавать по шаблону можно воспользоваться одним из вариантов:
1) проще всего скопировать файл шаблона в файл с именем будущего чертежа.
2) Можно еще воспользоваться методом DocumentCollection.Add, но при этом будет создан документ, а не база.
3) Открыть файл шаблона как Database и для неё сделать Wblock (без параметров) в новую базу.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение Дмитрий Загорулькин 08-10-2014, 14:49:06

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
А еще можешь попробовать 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.     }
     
« Последнее редактирование: 17-02-2014, 15:51:24 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Спасибо, понял.
В идеале, хотелось бы создать копию существующего чертежа, но без примитивов. А потом перенести в нее только нужные примитивы. Но цивилизованного способа для такого я не придумал, поэтому создание нового чертежа по шаблону - наиболее приемлемая альтернатива.
4-й метод мне очень нравится! Буду пробовать его применять.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
В идеале, хотелось бы создать копию существующего чертежа, но без примитивов. А потом перенести в нее только нужные примитивы. Но цивилизованного способа для такого я не придумал,
А в чем проблема? Database.Wblock в новую базу и удаляешь все примитивы из неё. Тоже вариант.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Не успел... :) Ну да ладно, всё равно напишу уж, зря, что ли царапал...
Код - 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);

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
А в чем проблема? Database.Wblock в новую базу и удаляешь все примитивы из неё.
Мне кажется, что это нецивилизованный способ. Если чертеж большой, то много лишней работы нужно будет проделать. К тому же, это чертеж, выполненный в вертикальном решении, перетащится еще куча вспомогательных ненужных данных, вычищать придется долго и кропотливо. А вариант с шаблоном мне все больше и больше нравится - в него можно вносить нужные изменения не затрагивая кода.

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
В идеале, хотелось бы создать копию существующего чертежа, но без примитивов.
А не проще тогда в чистую базу данных (new Db.Database(false, true);) банально импортировать все нужные тебе стили, слои и определения блоков?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Вариант с шаблоном мне все больше и больше нравится - в него можно вносить нужные изменения не затрагивая кода.
Если это устоявшийся шаблон - то ты прав. А если сценарий такой: дают чертеж и на основе его нужно сделать шаблон без примитивов - только установленные системные переменные, таблицы слоев, блоков, типов линий и т.д., то вполне себе нормальное решение.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
то вполне себе нормальное решение.
чем лучше обозначенного в #8?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
чем лучше обозначенного в #8?
В твоём варианте нужно:
1) Пройтись по списку системных переменных, хранящихся в базе и скопировать их в новую базу
2) Пройтись по всем стилям (слои, блоки, типы линий, текстовые стили ...), NOD и скопировать их.
Кода будет явно больше, нужно будет учесть все возможные варианты, и не думаю, что он будет быстрее.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Кода будет явно больше, нужно будет учесть все возможные варианты, и не думаю, что он будет быстрее.
А вы предлагаете выполнить общую итерацию, в которой удаляются все Entity?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
А вы предлагаете выполнить общую итерацию, в которой удаляются все Entity?
Тут тоже возможны варианты. Возможно не нужны примитивы только в ModelSpace, а блоки и примитивы на листах (например рамки и штампы) как раз нужны. Так что всё зависит от постановки задачи.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Если удалять всё одним махом:
Код - 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. }
то могут ли возникнуть такие ситуации, что удалить один объект мы не сможем, пока не будут предварительно удалены некоторые др. объекты, зависящие от него? Т.е. важен ли порядок удаления, или же зависимые будут удаляться автоматом?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
то могут ли возникнуть такие ситуации, что удалить один объект мы не сможем, пока не будут предварительно удалены некоторые др. объекты, зависящие от него? Т.е. важен ли порядок удаления?
Тут проблем быть не должно. Но! Таким образом ты удалишь все примитивы внутри блоков. Т.е блоки окажутся пустыми.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
А еще можешь попробовать 4-ый метод:
Все, проверил, прекрасно работает! Хочу заметить, что в методе Database.ReadDwgFile нужно указывать полный путь к шаблону, файл в путях поддержки сам не ищется. Хотя, возможно, что это нормально для NET.
Другие способы, про которые вы писали в этой теме, гораздо более трудоемки и не факт, что дадут нужный результат. С шаблоном же всегда можно оперативнее подстроиться под желания пользователей.
Еще раз спасибо за советы!

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Тут проблем быть не должно. Но! Таким образом ты удалишь все примитивы внутри блоков. Т.е блоки окажутся пустыми.
А, ну да... :) Нужно выполнять итерацию по модели и листам.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Все, проверил, прекрасно работает!
Отлично!
Хочу заметить, что в методе Database.ReadDwgFile нужно указывать полный путь к шаблону, файл в путях поддержки сам не ищется. Хотя, возможно, что это нормально для NET.
Это вообще нормально. :)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Ничего. Создается пустая база с настройка по-умолчанию для базы (никак не связанная ни с какими шаблонами).
Похоже, что метод Database.Wblock точно так же новый чертеж создает. Вытаскиваю объекты из чертежа этим методом. В результате, в новом чертеже совершенно другие единицы. В исходном метры, в получаемом - футы. Можно как-то эти настройки по умолчанию переопределять?

Update:
А, я там новую базу данных так же создаю: new Database(true, false). Понятно, почему "все по умолчанию".

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
А, я там новую базу данных так же создаю: new Database(true, false). Понятно, почему "все по умолчанию".
Разобрался? Теперь всё нормально?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Да, я разобрался, почему так происходит. А вот как с этим бороться - пока неясно. Наверное, тоже придется указывать конкретный шаблон для создания нового чертежа.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Database.Wblock (если использовать метод без параметров) создаёт новую базу с теми же параметрами, что и у базы, для которой этот метод выполняется. Так что единицы измерения должны быть одинаковы. Во всяком случае в чистом AutoCAD - Civil3D возможно обрабатывает единицы посвоему.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Да, этот вариант работает! Но, в новую БД копируются все объекты исходной БД, примитивы в том числе. По сути, создается полная копия исходного чертежа. Мне такое не подходит.
В общем, сделал тоже с использованием шаблона - хорошо работает, все устраивает.

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Хорошо работало и устраивало...
Возникли проблемы с аннотативными объектами. В исходном чертеже их видно, в получаемом - нет. Манипуляции с переменными не спасают.
Видимо, нужно еще дополнительно перетаскивать какие-то настройки чертежа, касающиеся аннотативности.

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
имеешь в виду, что у объектов, полученных с помощью wblock, слетает список их аннотативных масштабов?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
На всякий случай напоминаю, что масштабы аннотаций содержаться в словаре ACAD_SCALELIST:


Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Подумав, решил создавать полную копию чертежа и вычищать примитивы. Мало ли что потом еще вылезет...

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Подумав, решил создавать полную копию чертежа и вычищать примитивы. Мало ли что потом еще вылезет...
:D А ведь я советовал именно это сделать сразу!
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Это-то да, но по таким соблазнительным граблям было грех не пройтись :)