Анонимные блоки

Автор Тема: Анонимные блоки  (Прочитано 8500 раз)

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

Оффлайн Николай ГорловАвтор темы

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


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

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Анонимные блоки
« Ответ #1 : 22-02-2021, 16:15:45 »
1. Открываю файл, в котором в BTR лежат блоки (динамические и простые). Вставок в чертеж нет.
Причина в этом.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Анонимные блоки
« Ответ #2 : 22-02-2021, 16:34:57 »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Николай ГорловАвтор темы

  • ADN
  • *
  • Сообщений: 238
  • Карма: 34
Re: Анонимные блоки
« Ответ #3 : 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:  Может понапрягать автодеск? раз уж начали что-то делать, то пусть доделывают до конца (эт как из анекдота про деланье детей :) ) - Если чертеж от анонимных блоков должен автоочищаться, хоть об этом ничего нигде не сказано, то пусть он очищается ПОЛНОСТЬЮ, если не должен - то пусть блоки остаются в чертеже ПОЛНОСТЬЮ. Если блоку система сама присвоила уникальное имя, то пусть это имя ЗАКРЕПИТСЯ за этим блоком, а не меняется в зависимости от погоды за бортом, лунного календаря и т.п.

Оффлайн Николай ГорловАвтор темы

  • ADN
  • *
  • Сообщений: 238
  • Карма: 34
Re: Анонимные блоки
« Ответ #4 : 23-02-2021, 13:09:36 »
Итак, написал тестовую функцию, которая мониторит состояние блоков на протяжение всех махинаций.
Результат - если файл не закрывается, то конвертация туда-сюда с сохранением изменений после каждой конвертации выдает исходный файл с нормальными именами блоков.
Если функцию разбить на две части (в первой части - создание анонимных блоков и сохранение, а во второй - превращение анонимных блоков в нормальные и сохранение), то после открытия файла с анонимными блоками в живых остаются блоки U4, U5, U57, U58 (не знаю, что произошло, вроде бы ничего не менял, но теперь новые имена "U" не появляются), которые превращаются в 4 динамических блока.
При открытии файла есть заход в реактор AcEditorReactor::endDwgOpen (это для 20 акада, предыдущие - dwgFileOpened) и там делаем пробег по базе. в базе 4 блока, те, что написал выше. Размер файла ДО пересохранения говорит о том, что в нем лежат все блоки, только достучаться до них нельзя.
Почитал справку по поводу acdbSetReferenced. Если перевести, то получается, что функцию нужно использовать сразу после создания анонимного блока, иначе автокад в процессе открытия файла просто удалит анонимный блок. Использовал сразу после смены имени на "*U" - результат Acad::eOk, оставил и в реакторе - результат такой же как и без этой функции. Вот как-то так получается.

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Анонимные блоки
« Ответ #5 : 23-02-2021, 19:50:21 »
Может понапрягать автодеск?
Понапрягать можно. Но (!!!) ты дожен всё для них подготовить:
1) Полный код.
2) Тестовый чертеж.
3) Видео, воспроизводящее это поведение - в английской версии AutoCAD со всеми обновлениями.

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

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Анонимные блоки
« Ответ #6 : 23-02-2021, 21:32:32 »
Николай Горлов,
Я тут немного подумал и склоняюсь к мысли, что динамические блоки (тут сложно найти тонкую грань между динамическими и статическими  блоками - свойство/метод isDynamicBlock не показатель) не могут быть анонимными.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 534
  • Карма: 117
Re: Анонимные блоки
« Ответ #7 : 24-02-2021, 13:08:34 »
Если в двух словах, задумался о "защите" :) собственных блоков.
Если хочешь защитить свои блоки, разбей все блоки. Т.к. насколько помню, анонимные блоки легко переделать в обычные и использовать. 

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

Могу лишь предположить что автокад при открытии автоматом удаляет неиспользуемые анонимные блоки, и при необходимости вставляет новые анонимные блоки. В твоем случае блоки(BlockTableRecord) стали анонимными и все попали под удаление, кроме тех, которые были вставлены как(BlockReference). При этом может пострадать работоспособность динамических блоков, т.к. может быть удален нужный "главный" динамический блок(BlockTableRecord).

Оффлайн Николай ГорловАвтор темы

  • ADN
  • *
  • Сообщений: 238
  • Карма: 34
Re: Анонимные блоки
« Ответ #8 : 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. Вот такой закрученный сюжет :), в котором вроде бы бесполезная функция с одной стороны оказывается очень даже нужной с другой )))))))))))

Понапрягать можно. Но (!!!) ты дожен всё для них подготовить
сейчас слегка занят, да и главное понять, во что тыкать носом. в общем обязательно все подготовлю, но не на этой неделе.

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 534
  • Карма: 117
Re: Анонимные блоки
« Ответ #9 : 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 в блок

Оффлайн Николай ГорловАвтор темы

  • ADN
  • *
  • Сообщений: 238
  • Карма: 34
Re: Анонимные блоки
« Ответ #10 : 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" пояснил, если что :)

Кстати, что по коду? Есть ошибки? Может я чего не заметил.

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Анонимные блоки
« Ответ #11 : 25-02-2021, 18:34:50 »
Николай Горлов,
Не уверен, что это как-то поможет, но кто же это переименовывает блоки при итерировании по таблице блоков? Может всё-таки сначала получишь коллекцию AcDbObjectId для блоков, которые собираешься переименовывать, а потом будешь их переименовывать.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 534
  • Карма: 117
Re: Анонимные блоки
« Ответ #12 : 26-02-2021, 07:43:49 »
Стандартными средствами автокада? Научишь?
Я тебе ссылку на лисп скинул, который это делает. Поэтому твой вопрос, про "научить стандартными средствами автокада" мне не понятен.
Заходишь в редактор блока, вручную удаляешь все, что относится к динамике и т.д. ....

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

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

Кстати, что по коду? Есть ошибки? Может я чего не заметил.
Похоже ты переименовываешь все BlockTableRecord?
Т.е. пространства модели, листов, и внешние ссылки тоже?
« Последнее редактирование: 26-02-2021, 09:19:50 от Привалов Дмитрий »

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Анонимные блоки
« Ответ #13 : 26-02-2021, 10:12:33 »
Т.е. пространства модели, листов, и внешние ссылки тоже?
С пространством модели и листа все нормально. Они начинаются с звездочки. А вот на внешние ссылки нужно посмотреть внимательнее.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 534
  • Карма: 117
Re: Анонимные блоки
« Ответ #14 : 26-02-2021, 11:07:22 »
Еще нужно исключать имена блоков с подчеркиванием, типа "_Open90" как правило это блоки засечек, стрелок для размеров и мультивыносок.
Может еще что-то упустил.

Рассмотри возможность переименовать все свои блоки с префиксом, типа "моёёё_" или ввести одинаковое описание для своих блоков BlockTableRecord.Comments. По ним можно отбирать только свои блоки и переименовывать.

Оффлайн Lemieux

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Re: Анонимные блоки
« Ответ #15 : 26-02-2021, 11:43:49 »
а сделать не удобным использование БЕЗ arx-ины, за которую нужно платить деньги
А не проще написать плагин без которого блоки просто не юзабельны?

Оффлайн Николай ГорловАвтор темы

  • ADN
  • *
  • Сообщений: 238
  • Карма: 34
Re: Анонимные блоки
« Ответ #16 : 26-02-2021, 12:16:46 »
Не уверен, что это как-то поможет, но кто же это переименовывает блоки при итерировании по таблице блоков? Может всё-таки сначала получишь коллекцию AcDbObjectId для блоков, которые собираешься переименовывать, а потом будешь их переименовывать.
попробовал, результат тот же. а вообще странно получается - динамика остается всегда (видать из-за ссылок внутри бд на всякие там ручки, динамические операции), а статика ни к чему не привязанная удаляется всегда после прохода через dwgFileOpened, и не спасает даже функция acdbSetReferenced.
но если не проходить через dwgFileOpened, а восстанавливать имена открыв файл через readDwgFile, то все блоки (и статика, и динамика) восстанавливаются замечательно, чего мне в принципе хватит.
остался правда один файл, в которым с каждым закрыл/восстановил блоков становится меньше :) даже при использовании readDwgFile. причем удаляется как статика так и динамика с завидным постоянством. вот с ним сейчас и разбираюсь, что там откуда растет и на кого ссылается.

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

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


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

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

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

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

Второй файл у тебя отличается от первого -  внутрь динамических блоков вставлены обычные.
да, согласен, пропустил.

Оффлайн Николай ГорловАвтор темы

  • ADN
  • *
  • Сообщений: 238
  • Карма: 34
Re: Анонимные блоки
« Ответ #17 : 02-03-2021, 11:20:16 »
Вроде как поборол :). Теперь можно подытожить:
1. функция acdbSetReferenced обязательно нужна после переимнования блока (если нет вставок блока в чертеж или каких-то связей с бд чертежа). это проще, чем варганить завязку на кастомный объект, который по сути будет делать то же, что уже написанная функция.
2. имя *U, которое дается в процессе setName НЕ ЯВЛЯЕТСЯ УНИКАЛЬНЫМ и может произвольным образом поменяться на другое, так что лучше пользоваться handle

на картинке в двух столбиках отображены имя, хендл и *U имя при создании ананимного блока (первый столбец) и при обратном преобразовании (второй столбец)
ну и в подсвеченных ячейках видно, как имя данное при создании чудесным образом поменялось при повторном переименовании блоков (особенно порадовало последнее имя блока :) )
3. чертеж ни в коем случае нельзя открывать и сохранять в автокаде визуально (при открытии теряется доступ к элементам BTR, а сохранение делает эту потерю постоянной), только через readDwgFile.

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

По поводу запроса в автодеск... Сформировалось у меня 2 вопроса:
1. почему acdbSetReferenced не защищает анонимный статический блок от автоочистки, происходящей в dwgFileOpened
2. почему анонимные блоки самопроизвольно меняют имена (вот правда не выяснял в каком случае: в случае вызова readDwgFile или в случае изменения имен других блоков, к которым они не имеют никакого отношения и просто находятся рядышком в таблице блоков).
Вот только предчувствую я, что ответы мне не понравятся ))), да и сами ответы мне уже и не важны. Так что не буду мучать ни себя ни окружающих ))).

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Анонимные блоки
« Ответ #18 : 02-03-2021, 17:19:18 »
2. имя *U, которое дается в процессе setName НЕ ЯВЛЯЕТСЯ УНИКАЛЬНЫМ и может произвольным образом поменяться на другое, так что лучше пользоваться handle
Ну это как раз понятно. Оно генерируется (аналогично AcDbObjectId) при открытии файла.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение