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

ADN Club => ObjectARX => Тема начата: Николай Горлов от 22-02-2021, 13:17:53

Название: Анонимные блоки
Отправлено: Николай Горлов от 22-02-2021, 13:17:53
Если в двух словах, задумался о "защите" :) собственных блоков.
Да, конечно я понимаю, что лучший способ защиты чертежа или его частей (например, блоков) - это никому не давать этот самый чертеж, а высылать его фотографии, желательно еще и отретушированные :). Речь не об этом...
Одна из задачь, состоит в том, чтоб сделать все блоки в файле блоков анонимными. Да не вопрос. Сделал :). Подробности на видео.
Ну и кратенько опишу, чего там наснимал:
1. Открываю файл, в котором в BTR лежат блоки (динамические и простые). Вставок в чертеж нет.
2. Проверяю начальное состояние BTR. Всё ок, 58 блоков с нормальными именами на месте.
3. Запускаю команду для придания блокам анонимности.
4. Проверяю результат через ArxDbg. Всё хорошо.
5. Вручную сохраняю чертеж и снова проверяю содержимое BTR. Всё на месте.
6. Закрываю чертеж и открываю его заново.
7. Проверяю содержимое BTR в переоткрытом чертеже. Да-да, блоков стало слегка поменьше. Вместо 58 штук осталось 4.


Ну и вопрос, это я накосячил или это ОЖИДАЕМОЕ ПОВЕДЕНИЕ по удалению не используемых по мнению (блин, прям искуственный интеллект какой-то. удалил то не все блоки) автокада блоков? Если нужны исходники, могу выложить.
Название: Re: Анонимные блоки
Отправлено: Александр Ривилис от 22-02-2021, 16:15:45
1. Открываю файл, в котором в BTR лежат блоки (динамические и простые). Вставок в чертеж нет.
Причина в этом.
Название: Re: Анонимные блоки
Отправлено: Александр Ривилис от 22-02-2021, 16:34:57
Посмотри эту статью: https://adndevblog.typepad.com/autocad/2012/08/how-to-use-acdbsetreferenced.html
Название: Re: Анонимные блоки
Отправлено: Николай Горлов от 23-02-2021, 11:23:28
Цитировать
Посмотри эту статью: https://adndevblog.typepad.com/autocad/2012/08/how-to-use-acdbsetreferenced.html
попробовал. всё прошло с результатом Acad::eOk. Вот только проблемка :), на этапе dwgFileOpened (или в новых версиях - endDwgOpen) у меня в BTR лежат 4 анонимных блока (а не 58 начальных), которые и без этого танца отображаются. Так что вариант наверно имеет право на существование, но он абсолютно бесполезен :)

По поводу
Цитировать
Вставок в чертеж нет.
Вот прям даже не знаю что сказать:
1. Простые блоки с внятними именами сидят тихохонько в базе чертежа, даже если нет вставок в чертеж
2. Динамические блоки с нормальными именами также чувствуют себя хорошо.
3. Мусор, который по логике вещей ДОЛЖЕН самоуничтожаться (это я про A$..., который получается в результате Ctrl+C/Ctrl+V) - тоже гармонично смотрится в BTR.
А вот анонимным блокам не повезло. И, что самое интересное, остаются всегда одни и те же блоки (раз 8 пробовал повторить операцию) - блоки остаются одни и те же.
Кстати, 2 из 4 восстанавливаются до нормальных динамических блоков, а вот остальные два получают новые имена *U (еще не разобрался на каком этапе - сохранение, закрытие чертежа, открытие чертежа, попытка поменять имя другим анонимным блокам)

PS:  Может понапрягать автодеск? раз уж начали что-то делать, то пусть доделывают до конца (эт как из анекдота про деланье детей :) ) - Если чертеж от анонимных блоков должен автоочищаться, хоть об этом ничего нигде не сказано, то пусть он очищается ПОЛНОСТЬЮ, если не должен - то пусть блоки остаются в чертеже ПОЛНОСТЬЮ. Если блоку система сама присвоила уникальное имя, то пусть это имя ЗАКРЕПИТСЯ за этим блоком, а не меняется в зависимости от погоды за бортом, лунного календаря и т.п.
Название: Re: Анонимные блоки
Отправлено: Николай Горлов от 23-02-2021, 13:09:36
Итак, написал тестовую функцию, которая мониторит состояние блоков на протяжение всех махинаций.
Результат - если файл не закрывается, то конвертация туда-сюда с сохранением изменений после каждой конвертации выдает исходный файл с нормальными именами блоков.
Если функцию разбить на две части (в первой части - создание анонимных блоков и сохранение, а во второй - превращение анонимных блоков в нормальные и сохранение), то после открытия файла с анонимными блоками в живых остаются блоки U4, U5, U57, U58 (не знаю, что произошло, вроде бы ничего не менял, но теперь новые имена "U" не появляются), которые превращаются в 4 динамических блока.
При открытии файла есть заход в реактор AcEditorReactor::endDwgOpen (это для 20 акада, предыдущие - dwgFileOpened) и там делаем пробег по базе. в базе 4 блока, те, что написал выше. Размер файла ДО пересохранения говорит о том, что в нем лежат все блоки, только достучаться до них нельзя.
Почитал справку по поводу acdbSetReferenced. Если перевести, то получается, что функцию нужно использовать сразу после создания анонимного блока, иначе автокад в процессе открытия файла просто удалит анонимный блок. Использовал сразу после смены имени на "*U" - результат Acad::eOk, оставил и в реакторе - результат такой же как и без этой функции. Вот как-то так получается.
Название: Re: Анонимные блоки
Отправлено: Александр Ривилис от 23-02-2021, 19:50:21
Может понапрягать автодеск?
Понапрягать можно. Но (!!!) ты дожен всё для них подготовить:
1) Полный код.
2) Тестовый чертеж.
3) Видео, воспроизводящее это поведение - в английской версии AutoCAD со всеми обновлениями.

Название: Re: Анонимные блоки
Отправлено: Александр Ривилис от 23-02-2021, 21:32:32
Николай Горлов,
Я тут немного подумал и склоняюсь к мысли, что динамические блоки (тут сложно найти тонкую грань между динамическими и статическими  блоками - свойство/метод isDynamicBlock не показатель) не могут быть анонимными.
Название: Re: Анонимные блоки
Отправлено: Привалов Дмитрий от 24-02-2021, 13:08:34
Если в двух словах, задумался о "защите" :) собственных блоков.
Если хочешь защитить свои блоки, разбей все блоки. Т.к. насколько помню, анонимные блоки легко переделать в обычные и использовать. 

Ну и вопрос, это я накосячил или это ОЖИДАЕМОЕ ПОВЕДЕНИЕ по удалению не используемых по мнению (блин, прям искуственный интеллект какой-то. удалил то не все блоки) автокада блоков?
Конечно ты накосячил. Но чтоб понять в чем именно нужно детально смотреть чертеж и код.

Могу лишь предположить что автокад при открытии автоматом удаляет неиспользуемые анонимные блоки, и при необходимости вставляет новые анонимные блоки. В твоем случае блоки(BlockTableRecord) стали анонимными и все попали под удаление, кроме тех, которые были вставлены как(BlockReference). При этом может пострадать работоспособность динамических блоков, т.к. может быть удален нужный "главный" динамический блок(BlockTableRecord).
Название: Re: Анонимные блоки
Отправлено: Николай Горлов от 25-02-2021, 11:39:01
Я тут немного подумал и склоняюсь к мысли, что динамические блоки (тут сложно найти тонкую грань между динамическими и статическими  блоками - свойство/метод isDynamicBlock не показатель) не могут быть анонимными.
чего это? именно на анонимных блоках и построена вся работа с динамическими блоками, если верить логике автодеска. когда динамический блок вставляется, ему дается имя как и у родительской BTR. Дальше, любое изменение динамики приводит к рождению анонимного блока, который описывает текущее положение динамики, но ссылается на родительский. В итоге, если блок подергать 10 раз, мы получаем 10 анонимных блоков, каждый из которых описывает какое-то изменение динамики (это то и позволяет делать откат Ctrl+Z). После переоткрытия чертежа все анонимные блоки, которые не используются просто вычищаются. Странно, не удобно, но реализовано именно так. В свете всего этого становится понятно, зачем придумали функцию acdbSetReferenced (вот только работает она странноватенько).

Если хочешь защитить свои блоки, разбей все блоки. Т.к. насколько помню, анонимные блоки легко переделать в обычные и использовать.
Да я ж и не спорю, поэтому и написал в первом посте слово защита в кавычках. Задача скорей не защитить, а сделать не удобным использование БЕЗ arx-ины, за которую нужно платить деньги :).
По поводу защиты блоков и чертежей в автодеске придерживаются мнения, что все мы живем в каммунзме и всё, что нарисовано - общественная собственность (если не ошибаюсь, в начале существования автокада была возможность ставить пароль на блоки. также была возможность закрывать паролем весь чертеж. парольной защиты блоков уже нет в 2005 автокаде, парольный вход не поддерживается в 2020. зато везде пихают цифровые подписи, которые служат чисто для поддержания на плаву организаций, их выдающих и не обладают никакими защитными свойствами). было б здорово написать свой кастомный объект на основе блока (а лучше BTR), увы - нельзя, ибо сами автодесковцы говорят, что работает криво, да и пару лет назад я честно пытался. статические блоки - работают, динамика - не поддерживается.


Конечно ты накосячил. Но чтоб понять в чем именно нужно детально смотреть чертеж и код.
С этим никаких проблем нет, вот код функции
Код - C++ [Выбрать]
  1. void lockcur()
  2. {      
  3.         acutPrintf(_T("\n*Начало..."));
  4.         int count1 = 0;
  5.         //-> для начала пробежимся по BTR, сделаем все наши блоки анонимными
  6.         AcDbBlockTable* pBlockTable;
  7.         if (Acad::eOk == acdbCurDwg()->getSymbolTable(pBlockTable, AcDb::kForRead))
  8.         {
  9.                 AcDbBlockTableIterator *pBlockTableIterator = NULL;
  10.                 if (Acad::eOk == pBlockTable->newIterator(pBlockTableIterator, true))
  11.                 {
  12.                         for (; !pBlockTableIterator->done(); pBlockTableIterator->step())
  13.                         {
  14.                                 AcDbObjectId eId;
  15.                                 ACHAR * szBuffer;
  16.                                 pBlockTableIterator->getRecordId(eId);
  17.                                 AcDbBlockTableRecordPointer pRec(eId, AcDb::kForRead);
  18.                                 if (Acad::eOk != pRec.openStatus()) continue;
  19.  
  20.                                 pRec->getName(szBuffer);
  21.                                 CString realName = szBuffer;
  22.                                 acutDelString(szBuffer);
  23.                                 if (realName.Find(_T('*')) == -1 && realName.Find(_T('$')) == -1)
  24.                                 {
  25.                                         count1++;
  26.                                         if (Acad::eOk != pRec->upgradeOpen()) continue;
  27.                                         pRec->setName(_T("*U"));
  28.                                         pRec->downgradeOpen();
  29.                                         if (Acad::eOk != acdbSetReferenced(eId))
  30.                                                 acutPrintf(_T("\nError acdbSetReferenced"));
  31.                                         AcDbObjectIdArray blkInserts; blkInserts.removeAll();
  32.                                         pRec->getBlockReferenceIds(blkInserts);
  33.                                         pRec->getName(szBuffer);
  34.                                         CString anonymouseName = szBuffer;
  35.                                         acutDelString(szBuffer);
  36.                                         acutPrintf(_T("\n%s : %s"), realName.GetString(), anonymouseName.GetString());
  37.                                 }
  38.                         }
  39.                 }
  40.                 if (pBlockTableIterator != NULL) delete pBlockTableIterator;
  41.                 pBlockTable->close();
  42.         }      
  43.         acutPrintf(_T("\n*Обработано %d блоков"), count1);
  44.  
  45.         count1 = 0;
  46.  
  47.         acutPrintf(_T("\n*Проверка количества блоков в БД чертежа после анонимизации :) ..."));
  48.         if (Acad::eOk == acdbCurDwg()->getSymbolTable(pBlockTable, AcDb::kForRead))
  49.         {
  50.                 AcDbBlockTableIterator *pBlockTableIterator = NULL;
  51.                 if (Acad::eOk == pBlockTable->newIterator(pBlockTableIterator, true))
  52.                 {
  53.                         for (; !pBlockTableIterator->done(); pBlockTableIterator->step())
  54.                         {
  55.                                 AcDbObjectId eId;
  56.                                 ACHAR * szBuffer;
  57.                                 pBlockTableIterator->getRecordId(eId);
  58.                                 AcDbBlockTableRecordPointer pRec(eId, AcDb::kForRead);
  59.                                 if (Acad::eOk != pRec.openStatus()) continue;
  60.  
  61.                                 pRec->getName(szBuffer);
  62.                                 CString realName = szBuffer;
  63.                                 acutDelString(szBuffer);
  64.                                 if (realName.Find(_T("*U")) != -1)
  65.                                 {
  66.                                         count1++;
  67.                                         acutPrintf(_T("\n%d. %s"), count1, realName.GetString());
  68.                                 }
  69.                         }
  70.                 }
  71.                 if (pBlockTableIterator != NULL) delete pBlockTableIterator;
  72.                 pBlockTable->close();
  73.         }
  74.  
  75.         CString filePath = curDoc()->fileName();
  76.         acutPrintf(_T("\nЗапись в файл: %s"), filePath.GetString());
  77.         if (Acad::eOk != acdbCurDwg()->saveAs(filePath.GetString(), true, AcDb::kDHL_1024))
  78.         {
  79.                 acutPrintf(_T("\n*** Не смогла я записать файл, увы"));
  80.         }
  81.         //<-
  82.  
  83.         count1 = 0;
  84.         acutPrintf(_T("\n*Проверка количества блоков в БД чертежа после сохранения..."));
  85.         if (Acad::eOk == acdbCurDwg()->getSymbolTable(pBlockTable, AcDb::kForRead))
  86.         {
  87.                 AcDbBlockTableIterator *pBlockTableIterator = NULL;
  88.                 if (Acad::eOk == pBlockTable->newIterator(pBlockTableIterator, true))
  89.                 {
  90.                         for (; !pBlockTableIterator->done(); pBlockTableIterator->step())
  91.                         {
  92.                                 AcDbObjectId eId;
  93.                                 ACHAR * szBuffer;
  94.                                 pBlockTableIterator->getRecordId(eId);
  95.                                 AcDbBlockTableRecordPointer pRec(eId, AcDb::kForRead);
  96.                                 if (Acad::eOk != pRec.openStatus()) continue;
  97.  
  98.                                 pRec->getName(szBuffer);
  99.                                 CString realName = szBuffer;
  100.                                 acutDelString(szBuffer);
  101.                                 if (realName.Find(_T("*U")) != -1)
  102.                                 {
  103.                                         count1++;
  104.                                         acutPrintf(_T("\n%d. %s"), count1, realName.GetString());
  105.                                 }
  106.                         }
  107.                 }
  108.                 if (pBlockTableIterator != NULL) delete pBlockTableIterator;
  109.                 pBlockTable->close();
  110.         }
  111. }
Чертеж будет во вложениях. В чертеже 58 блоков с нормальными именами. Открываем чертеж, делаем его текущим. Запускаем команду, выполняющую функцию, написанную выше. В логе командной строки будет выведена информация о текущем состянии дел. Сразу идет сопоставление реального имени и анонимного. Потом еще один пробег по БД, с отображением всех анонимных BTR, потом сохранение чертежа и снова отображение всего, что осталось в БД после сохранения.
После этого чертеж нужно закрыть и открыть заново. И попытаться объяснить, почему вместо 58 блоков осталось 4 (вставок нет, использования в других блоках нет, а они остались). Функция acdbSetReferenced использовалась 58 раз, а видим 4 (если ей НЕ пользоваться, мы тожеж увидим те же 4 блока через ArxDbg или утилиты очистки чертежа, если что :) )

А теперь взрыв мозга... Если всё это проделать БЕЗ физического открытия чертежа (пользуемся readDwgFile), то видно все 58 анонимных блоков. В этом случае не вызывается реактор dwgFileOpened, который судя по справке и удаляет не используемые блоки (которые призвана защитить функция acdbSetReferenced!!!). Вот правда если "анонимизировать" блоки БЕЗ функции acdbSetReferenced, то в процессе открытия через readDwgFile их тоже всего 4. Вот такой закрученный сюжет :), в котором вроде бы бесполезная функция с одной стороны оказывается очень даже нужной с другой )))))))))))

Понапрягать можно. Но (!!!) ты дожен всё для них подготовить
сейчас слегка занят, да и главное понять, во что тыкать носом. в общем обязательно все подготовлю, но не на этой неделе.
Название: Re: Анонимные блоки
Отправлено: Привалов Дмитрий от 25-02-2021, 13:04:47
сейчас слегка занят, да и главное понять, во что тыкать носом.
Предположение, почему остались 4 блока:
1. Все анонимные блоки автокад удаляет при открытии, если они не нужны. Т.е. они не имеют вставок и на них никто не ссылается.
2. У тебя в чертеже 4 динамических блока.
IsDynamicBlock=True
ДКНЛ1_04_1_11_Д_натяжная_проф_дин
ДКНЛ1_04_концевая_план_дин
Перевод стрелочный ДКНУ 1 (Р33)
Перевод стрелочный ДКНУ1 (Р24)

Возможно они и не удалились.
Попробуй открытый чертеж, с 4мя блоками сохранить, закрыть и открыть еще раз. Возможно эти 4 блока также пропадут. (Ну или не пропадут. :-) )

Задача скорей не защитить, а сделать не удобным использование БЕЗ arx-ины, за которую нужно платить деньги :).
Обычные блоки, если оставляешь, особо не защитишь, удобство использования сильно не поменяется.
Динамические блоки можно в статические перевести.

https://forum.dwg.ru/showthread.php?p=735810
Вот LISP, поэкспериментируй сначала с его возможностями.
Возможно в нем все, что тебе нужно для защиты.
....
BGBLDYN2A - Преобразовывает динамические блоки в анонимные
BGBLDYN2S - Преобразовывает динамические блоки в статические
BGBLALLDYN2A - Преобразовывает ВСЕ динамические блоки в анонимные   
BGBLALLDYN2S - Преобразовывает ВСЕ динамические блоки в статические 

А эта команда скорее всего легко снимает твою текущую защиту.
U2B - Преобразовать UNNAMED в блок
Название: Re: Анонимные блоки
Отправлено: Николай Горлов от 25-02-2021, 16:14:16
Предположение, почему остались 4 блока:
1. Все анонимные блоки автокад удаляет при открытии, если они не нужны. Т.е. они не имеют вставок и на них никто не ссылается.
2. У тебя в чертеже 4 динамических блока.
Согласен. В этом чертеже 4 динамических и 54 статических. Вставок в чертеж, перекрестных ссылок и т.д. и т.п. нет вообще. Метод обработки блоков командой одинаковый. Открывать и пересохранять можно пока не устанет рука, но их по-прежнему будет 4. Да, в этом файле все 4 оказались динамическими. Можно было б предположить, что удаляется статика и удаляется всегда. А вот и нет. Еще один файл блоков (эт я так их все сам в свободный доступ выложу :) :) :) ) во вложениях. С ним вообще всё проходит шикарно. Внутри 33 блока. Все 33 замечательно видны в бд чертежа в виде анонимных после переоткрытия файла, и все 33 замечательно восстанавливают свои имена даже при работе с текущим чертежом (а в предыдущем файле всё ок только если его не открывать физически в автокаде).

Цитировать
Динамические блоки можно в статические перевести.
Стандартными средствами автокада? Научишь? :)
Представь себе ситуацию, когда компьютер не домашний, где пользователь делает всё что хочет, а рабочий, где даже флешки закрыты и нужен сисадмин, чтоб скинуть файл в нужную папку, вытащенный из почты. Теперь представь, что просто о существовании анонимных блоков знает 1-2% рядовых пользователей автокада, и что 0.5% из них пытались понять, как создать этот самый анонимный блок (да-да, средствами автокада, а не сторонними лиспинами). Речь идет не о свободно занятых художниках, которые от безделия читают тонны литературы и рукаблудят с компьютером, а о производственниках, задача которых состоит в оформлении документации (собирать файл как пазл из кусков, печатать и отдавать на подпись).
PS: Чисто ради прикола отдал файл сотруднику со словами - видишь эту заблокированную ерунду. Это динамический блок. Вставь его в другой чертеж или хоть динамику поменяй. Пока просто смотрит на экран и пытается взорвать )))). И это человек, который с автокадом работает уже лет 15, если не больше.
PS2: На самом деле - создание анонимного блока - это только один из этапов. Анонимность позволяет скрыть блок от стандартной автокадовской вставки в чертеж или войти в редактор блоков. Но, если сам блок находится в чертеже, то никто не мешает его скопировать и утянуть куда-то со всей причитающейся динамикой. Значит нужно еще в случае визуального отображения блока прибить его гвоздём к точке и смазать клеем все подвижные части :) в случае когда закончилась подписка на программу, ну а в случае, когда и программы то нет, а файл просто открывают на компьютере написать красивенько "УВЫ, ЗДЕСЬ БЫЛ КРАСИВЫЙ БЛОК", или как-то так. Это я "PS" пояснил, если что :)

Кстати, что по коду? Есть ошибки? Может я чего не заметил.
Название: Re: Анонимные блоки
Отправлено: Александр Ривилис от 25-02-2021, 18:34:50
Николай Горлов,
Не уверен, что это как-то поможет, но кто же это переименовывает блоки при итерировании по таблице блоков? Может всё-таки сначала получишь коллекцию AcDbObjectId для блоков, которые собираешься переименовывать, а потом будешь их переименовывать.
Название: Re: Анонимные блоки
Отправлено: Привалов Дмитрий от 26-02-2021, 07:43:49
Стандартными средствами автокада? Научишь?
Я тебе ссылку на лисп скинул, который это делает. Поэтому твой вопрос, про "научить стандартными средствами автокада" мне не понятен.
Заходишь в редактор блока, вручную удаляешь все, что относится к динамике и т.д. ....

С ним вообще всё проходит шикарно. Внутри 33 блока. Все 33 замечательно видны в бд чертежа в виде анонимных после переоткрытия файла
Второй файл у тебя отличается от первого -  внутрь динамических блоков вставлены обычные.
Динамические блоки, переименованные как анонимные, как мы выяснили не удаляются. А обычные при этом удаляются.
Соответственно, если тебе нужно сохранить обычные блоки, создай динамический блок и вставь внутрь обычные. В этом случае, после переименования в анонимные все сохранится после открытия чертежа.

Если тебе нравится такой способ защиты блоков, используй!

Кстати, что по коду? Есть ошибки? Может я чего не заметил.
Похоже ты переименовываешь все BlockTableRecord?
Т.е. пространства модели, листов, и внешние ссылки тоже?
Название: Re: Анонимные блоки
Отправлено: Александр Ривилис от 26-02-2021, 10:12:33
Т.е. пространства модели, листов, и внешние ссылки тоже?
С пространством модели и листа все нормально. Они начинаются с звездочки. А вот на внешние ссылки нужно посмотреть внимательнее.
Название: Re: Анонимные блоки
Отправлено: Привалов Дмитрий от 26-02-2021, 11:07:22
Еще нужно исключать имена блоков с подчеркиванием, типа "_Open90" как правило это блоки засечек, стрелок для размеров и мультивыносок.
Может еще что-то упустил.

Рассмотри возможность переименовать все свои блоки с префиксом, типа "моёёё_" или ввести одинаковое описание для своих блоков BlockTableRecord.Comments. По ним можно отбирать только свои блоки и переименовывать.
Название: Re: Анонимные блоки
Отправлено: Lemieux от 26-02-2021, 11:43:49
а сделать не удобным использование БЕЗ arx-ины, за которую нужно платить деньги
А не проще написать плагин без которого блоки просто не юзабельны?
Название: Re: Анонимные блоки
Отправлено: Николай Горлов от 26-02-2021, 12:16:46
Не уверен, что это как-то поможет, но кто же это переименовывает блоки при итерировании по таблице блоков? Может всё-таки сначала получишь коллекцию AcDbObjectId для блоков, которые собираешься переименовывать, а потом будешь их переименовывать.
попробовал, результат тот же. а вообще странно получается - динамика остается всегда (видать из-за ссылок внутри бд на всякие там ручки, динамические операции), а статика ни к чему не привязанная удаляется всегда после прохода через dwgFileOpened, и не спасает даже функция acdbSetReferenced.
но если не проходить через dwgFileOpened, а восстанавливать имена открыв файл через readDwgFile, то все блоки (и статика, и динамика) восстанавливаются замечательно, чего мне в принципе хватит.
остался правда один файл, в которым с каждым закрыл/восстановил блоков становится меньше :) даже при использовании readDwgFile. причем удаляется как статика так и динамика с завидным постоянством. вот с ним сейчас и разбираюсь, что там откуда растет и на кого ссылается.

Похоже ты переименовываешь все BlockTableRecord?
Т.е. пространства модели, листов, и внешние ссылки тоже?
не, ни пространства модели/листа, ни огрызки от копирования, ни другие анонимные блоки я не трогаю. короче, пропускается всё, что начинается на * или содержит $ в своем имени.

внешних ссылок или чего-то другого в файле нет и быть не может. это файл мой, который я (ну, не совсем я - сотрудники) наполняю блоками оборудования, и отдаю пользователям. через arx-ину формируется окно списка оборудования с картинками, которые появляются при клацанье на строку списка и происходит вставка блока в указанную точку по двойному щелчку. вот как-то так выглядит само окно
(https://i.postimg.cc/q6r2tsWn/blks.png) (https://postimg.cc/q6r2tsWn)

вот задача первая - сделать так, чтоб файлы блоков было бессмысленно утаскивать на компьютер без этой arx-ины при условии, что человек не знает словосочитания "анонимные блоки".
ну а вторая задача - мои блоки вставленные в чертеж должны перестать копироваться/редактироваться/взрываться/переноситься/обладать динамическими свойствами при условии, что arx-ина говорит об окончании подписки, либо, если arx-ины вообще нет в загруженных приложениях - вместо блоков идет строка текста. в случае возобновления подписки блоки опять обретают нормальные имена и все свойства автокадовских блоков.

первая задача - практически решна, по крайней мере основной смысл понятен, осталось доработать напильником :), со второй - проблем практически нет (верней есть одна, но я о ней еще не думал). на момент закрытия чертежа (при условии, что файл редактировался и сохранялся) все мои блоки, вставленные в чертеж становятся анонимными, затем на них навешивается кастомный объект на основе AcDbEntity. Та же беда происходит при окончании подписки. При открытии файла в акаде в реакторе dwgFileOpened происходит обратный процесс и на выходе пользователь видит нормальные блоки, опять же при условии существования подписки. Если подписка кончилась, но он види красивую картинку, которую нельзя ни перенести, ни скопировать, ни расчленить. Но с чертежом дальше можно продолжать работать. Что он нарисовал сам я блокировать не имею права, да и желания как-то тоже пакостить нет. Вот в целом вся задумка выглядит так.

А не проще написать плагин без которого блоки просто не юзабельны?
и встроить dwg-шник(и) внутрь ресурсов arx-ины? если нет, то как раз о таком плагине и идет речь. ну а встраивать в ресурсы смысла нет - блоки постоянно пополняются. сейчас уже где-то полторы тысячи. год назад было штук 800.

Я тебе ссылку на лисп скинул, который это делает. Поэтому твой вопрос, про "научить стандартными средствами автокада" мне не понятен.
да, тут я слегка натупил, мыслями был в анонимных блоках. ну и мысли были о том, что стандартными средствами автокада ни превратить блок в анонимный, ни вернуть ему нормальное имя в принципе не возможно. а превратить динамику в статику - не проблема.

Второй файл у тебя отличается от первого -  внутрь динамических блоков вставлены обычные.
да, согласен, пропустил.
Название: Re: Анонимные блоки
Отправлено: Николай Горлов от 02-03-2021, 11:20:16
Вроде как поборол :). Теперь можно подытожить:
1. функция acdbSetReferenced обязательно нужна после переимнования блока (если нет вставок блока в чертеж или каких-то связей с бд чертежа). это проще, чем варганить завязку на кастомный объект, который по сути будет делать то же, что уже написанная функция.
2. имя *U, которое дается в процессе setName НЕ ЯВЛЯЕТСЯ УНИКАЛЬНЫМ и может произвольным образом поменяться на другое, так что лучше пользоваться handle
(https://i.postimg.cc/5XtHZ31g/blks.png) (https://postimg.cc/5XtHZ31g)
на картинке в двух столбиках отображены имя, хендл и *U имя при создании ананимного блока (первый столбец) и при обратном преобразовании (второй столбец)
ну и в подсвеченных ячейках видно, как имя данное при создании чудесным образом поменялось при повторном переименовании блоков (особенно порадовало последнее имя блока :) )
3. чертеж ни в коем случае нельзя открывать и сохранять в автокаде визуально (при открытии теряется доступ к элементам BTR, а сохранение делает эту потерю постоянной), только через readDwgFile.

Ну вот в принципе и все подводные камни, через которые я прошел. Ах да, еще... при использовании handle абсолютно не важно происходит переименование в одном цикле при переборе всех BTR или первый цикл на получение имен/id BTR а вторым пробегом замена имени. Если пользоваться именами, то лучше работать в два пробега, хз почему, но на одном из файлов были проблемы.

По поводу запроса в автодеск... Сформировалось у меня 2 вопроса:
1. почему acdbSetReferenced не защищает анонимный статический блок от автоочистки, происходящей в dwgFileOpened
2. почему анонимные блоки самопроизвольно меняют имена (вот правда не выяснял в каком случае: в случае вызова readDwgFile или в случае изменения имен других блоков, к которым они не имеют никакого отношения и просто находятся рядышком в таблице блоков).
Вот только предчувствую я, что ответы мне не понравятся ))), да и сами ответы мне уже и не важны. Так что не буду мучать ни себя ни окружающих ))).
Название: Re: Анонимные блоки
Отправлено: Александр Ривилис от 02-03-2021, 17:19:18
2. имя *U, которое дается в процессе setName НЕ ЯВЛЯЕТСЯ УНИКАЛЬНЫМ и может произвольным образом поменяться на другое, так что лучше пользоваться handle
Ну это как раз понятно. Оно генерируется (аналогично AcDbObjectId) при открытии файла.