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

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

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. }
то могут ли возникнуть такие ситуации, что удалить один объект мы не сможем, пока не будут предварительно удалены некоторые др. объекты, зависящие от него? Т.е. важен ли порядок удаления, или же зависимые будут удаляться автоматом?