Создание и настройка динамических блоков в чертеже без его открытия

Автор Тема: Создание и настройка динамических блоков в чертеже без его открытия  (Прочитано 6497 раз)

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

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

  • Administrator
  • *****
  • Сообщений: 12569
  • Карма: 1632
  • Рыцарь ObjectARX
  • Skype: rivilis
Владимир Шу,
Обратил внимание на две вещи:
1) Количество динамических свойств у блока под красным текстом на два больше чем у двух других
2) В нём имеется два свойства, в имени которых есть пробел: "B_shiftMiddle X" и "B_shiftMiddle Y"
Возможно это как-то связано.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 565
  • Карма: 125
    • ПГСу Бложик
Количество динамических свойств у блока под красным текстом на два больше чем у двух других
1. Которые я не трогаю и не меняю, т.к. они  в другой видимости, более того, залез и удалил это свойство, все равно падает.
2. Название дин. свойства "B_shiftMiddle", а Х и Y через пробел это автокад дорисовывает, это координаты точки.

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 565
  • Карма: 125
    • ПГСу Бложик
Хм... Есть подозрение, что проблема где-то в передаче определения блока в новую базу. Попробую вечером поковырять.
Неа, но есть нюанс....
Я еще порезал твой код и теперь размножаю этот блок внутри того же файла
И все работает, ровно до тех пор, пока не включишь прогресс бар.
т.е. в том виде в котором код в этом топике, блок размножается и автокад не падает, но стоит раскоментировать строки с прогресс баром и получаю не фатал, а уже надоевшую до боли картинку:


Т.е. есть какая то проблема и с переносом описания блока и с самим блоком что-то не так.

Код - C# [Выбрать]
  1.     [CommandMethod("aaa")]
  2.     public void InsertAndSettingsAAA()
  3.     {
  4.       Document adoc = Application.DocumentManager.MdiActiveDocument;
  5.       Editor ed = adoc.Editor;
  6.       Database db = adoc.Database;
  7.  
  8.       PromptEntityOptions entOpts = new PromptEntityOptions("\nSelect dynamic block: ");
  9.       entOpts.SetRejectMessage("This is not block!");
  10.       entOpts.AddAllowedClass(typeof(BlockReference), true);
  11.  
  12.       PromptEntityResult entRes = ed.GetEntity(entOpts);
  13.       if (entRes.Status != PromptStatus.OK) return;
  14.  
  15.       ObjectId bTabRecId = ObjectId.Null;
  16.       Dictionary<string, object> blkDynProps = new Dictionary<string, object>();
  17.       Dictionary<string, string> attribs = new Dictionary<string, string>();
  18.  
  19.       using (Transaction tr = db.TransactionManager.StartTransaction())
  20.       {
  21.         BlockReference bref = tr.GetObject
  22.             (entRes.ObjectId, OpenMode.ForRead) as BlockReference;
  23.         if (bref.IsDynamicBlock)
  24.         {
  25.           bTabRecId = bref.DynamicBlockTableRecord;
  26.           foreach (DynamicBlockReferenceProperty dynProp
  27.               in bref.DynamicBlockReferencePropertyCollection)
  28.           {
  29.             blkDynProps[dynProp.PropertyName] = dynProp.Value;
  30.           }
  31.         }
  32.         tr.Commit();
  33.       }
  34.  
  35.       if (bTabRecId.IsNull || blkDynProps.Count == 0)
  36.       {
  37.         ed.WriteMessage("\nBlock without dynamic props! Exit.");
  38.         return;
  39.       }
  40.       //var pm = new ProgressMeter();
  41.       //pm.SetLimit(50);
  42.       //pm.Start("Создание и редактирование блоков");
  43.  
  44.       for (int i = 0; i < 50; i++)
  45.       {
  46.         var bRefId = Class2.CreateBlockReference(new Point3d(0, i * 1000, 0),
  47.           bTabRecId, db.CurrentSpaceId, db.LayerZero, 1, blkDynProps, attribs);
  48.  
  49.         //pm.MeterProgress();
  50.         //System.Windows.Forms.Application.DoEvents();
  51.       }
  52.       //pm.Stop();
  53.     }

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

  • ADN
  • *
  • Сообщений: 2433
  • Карма: 683
  • LISP/C#, AutoCAD/Civil 3D
  • Skype: zagor_dmtr
Меня смущает массив внутри блока. Массив - относительно новый объект AutoCAD. А в проблемном блоке применяется динамическая операция к массиву. В двух других, насколько я понял, такого нет. Возможно, что это такой баг программной работы с динамическим блоком с массивом внутри, который участвует в динамических операциях.
Массив сам по себе - это тоже динамический блок, только особым образом самим автокадом обрабатывается:
((-1 . <Имя объекта: 15fa5d22ef0>) (0 . "INSERT") (5 . "114D7") (102 . "{ACAD_REACTORS") (330 . <Имя объекта: 15fa5d40890>) (102 . "}") (330 . <Имя объекта: 15f9439e1f0>) (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbBlockReference") (2 . "*U69") (10 -7.10543e-15 35.0 0.0) (41 . 1.0) (42 . 1.0) (43 . 1.0) (50 . 0.0) (70 . 0) (71 . 0) (44 . 0.0) (45 . 0.0) (210 0.0 0.0 1.0))
И получается, что надо скомбинировать две динамики, да ещё и в неактивном документе, вне редактора. Думаю, проблема в этом.
Или, как вариант, проблема возникает при копировании определения блока. Получается, надо скопировать определение самого блока, плюс определение блока массива. Да ещё и с конкретной динамической вариацией. Возможно, API такого просто не умеет, либо делает неправильно.

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 565
  • Карма: 125
    • ПГСу Бложик
Дим, там рядом блок "Верхняя юбка B-B(Правая)", там тоже есть массив и этот блок работает нормально.

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

  • ADN
  • *
  • Сообщений: 2433
  • Карма: 683
  • LISP/C#, AutoCAD/Civil 3D
  • Skype: zagor_dmtr
А в проблемном блоке применяется динамическая операция к массиву. В двух других, насколько я понял, такого нет.
Вот в чём может быть разница.
Можешь выложить готовый тестовый проект для воспроизведения бага? Попробую погонять отладкой.

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 565
  • Карма: 125
    • ПГСу Бложик
А может и из-за массива.... делал проект для форума и решил потестировать перед отправкой.... один из ранее работавших блоков отказался работать и теперь вешает автокад. Блин, как это работает!??!?!

Проект и тестовый файл прилагаю.


ЗЫ.
Залез ковыряться в блок.... я конечно тупенький, но КАК ЭТО СДЕЛАНО?!? Каким образом удалось связать пользовательские параметры динамического блока с настройками массива, еще и так, что бы это работало?!?

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

  • ADN
  • *
  • Сообщений: 2433
  • Карма: 683
  • LISP/C#, AutoCAD/Civil 3D
  • Skype: zagor_dmtr
Я тоже такое впервые вижу. А это сторонние блоки? Может быть, это какое-то недокументированное поведение массива внутри блока.

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 565
  • Карма: 125
    • ПГСу Бложик
Я не знаю, мне эти блоки прислали. Я спросил у пользователя, как это сделано, может расскажет.
Мне стоило не торопиться, а самому поискать: https://forum.dwg.ru/showthread.php?t=140841
Цитировать
Кратко: создать в редакторе блоков переменную и в массиве в величину шага вбить эту переменную вместо числа. Вводить потом в свойствах.

Создал по этой подсказке блок и автокад ложится.
Наверное можно сказать, что причину нашли, теперь вопрос что делать?
« Последнее редактирование: 19-04-2021, 08:03:58 от Владимир Шу »

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 565
  • Карма: 125
    • ПГСу Бложик
Александр Наумович, я догадываюсь, что силами нашего форума эту задачу не решить, собственно не могли бы Вы переправить этот вопрос в автодеск?
Чёртика выпустили из табакерки и этих блоков с каждым днем будет все больше и как то с ними нужно работать. Тестовый проект и файл с блоками выложены несколькими сообщениями ранее.

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

  • Administrator
  • *****
  • Сообщений: 12569
  • Карма: 1632
  • Рыцарь ObjectARX
  • Skype: rivilis
Александр Наумович, я догадываюсь, что силами нашего форума эту задачу не решить, собственно не могли бы Вы переправить этот вопрос в автодеск?
Чёртика выпустили из табакерки и этих блоков с каждым днем будет все больше и как то с ними нужно работать. Тестовый проект и файл с блоками выложены несколькими сообщениями ранее.
Я могу переправить вопрос в ADN DevHelp при выполнении следующих условий:
1. Ты создаёшь тестовый проект с нуля (без никаких package, SafeOpen и т.д.) - никто с той стороны не будет разбираться с этим. Код должен быть максимально простым. Комментарии, если они нужны, на английском.
2. Проект должен быть для последних версий AutoCAD. Если ошибка не будет воспроизводится в AutoCAD 2022 - отправлять бесполезно. Это будет значить, что ошибку нашли и исправили и к старым версиям возвращаться не будут.
3. Ты объясняешь подробно что должно быть и что не так и записываешь видео при помощи Autodesk Screencast в одной из трех последних версий AutoCAD.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 565
  • Карма: 125
    • ПГСу Бложик
Хорошо, за праздники подготовлю.
небольшое уточнение: Использовать официальный Nuget пакет так же нельзя?

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 565
  • Карма: 125
    • ПГСу Бложик
Если ошибка не будет воспроизводится в AutoCAD 2022 - отправлять бесполезно.
ОС: ставил с образа Win10_20H2_v2_Russian_x64.iso скаченного с сайта MS
Autocad: ставил с веб установщика AutoCAD_2022_English_Win_64bit_di_en-US_setup_webinstall.exe с 30 дневным тестом.

Ошибка не воспроизводится, код из 21 сообщения работает стабильно, хоть с прогресс баром, хоть без него, хоть с тестовым файлом, хоть с вновь созданным блоком. За два десятка прогонов и попыток, уронить автокад не удалось. Так что записывать видео не стал и вопрос с отправкой в ADN снимается. Увы.

И если я правильно понимаю, то пока единственный выход для меня, с моим 2017, это проверять определение блока на наличие в нем массива (bool = AssocArray.IsAssociativeArray(ObjectId)) и если он там есть, то информировать об этом пользователя и игнорировать эти блоки, но это как то не правильно, т.к. массив может не иметь связей с параметрами блока... а как проверить наличие связей я пока не понял, "будем искать" и буду благодарен за подсказки.