Робота з неактивним документом, autolisp

Переважна більшість Лісп-функцій, які відображаються на форумах і сайтах, працюють з поточним документом. Як правило, цього достатньо. Але що робити, якщо треба обробляти кілька документів? Тут я хотів би розглянути деякі питання, пов'язані саме з обробкою неактивного документа.

У поточному (активному) документі програмісту доступні всі можливості lisp'a - це і командні методи, і інтерактивне формування наборів примітивів, і ename-методи, і activex. Але варто тільки заїкнутися про обробку неактивного документа, як перелік можливих засобів моментально звужується до стану "ActiveX і практично більше нічого".

Перш ніж приступати до подальших міркувань, нагадаю, що AutoCAD повинен бути переведений в багатодокументний режим (системна змінна SDI дорівнює 0).

Перше бажання - написати scr-файл (можливо, програмно) за алгоритмом: відкрити файл, завантажити Лісп, виконати Лісп, зберегти файл, відкрити наступний і т.д .; і запустити його на виконання. Чим поганий подібний підхід? Ну, хоча б тим, що оброблювані файли можуть бути дуже важкими, часу на їх відкриття і регенерацію може йти неміряно. Усередині файлів можуть зустрітися, наприклад, проксі-об'єкти. Або буде запит на пошук shx-файлу (про те, як від цього запиту позбутися, поговоримо пізніше). Або ще чогось ... Коротше, доведеться сидіти поруч з комп'ютером і чекати, поки він не закінчить виконання скрипта. Не, це нудно.

Третій варіант - Залізьте досить глибоко в нетрі AutoCAD і відкривати файл dwg без активізації. На ньому я і хотів би зупинитися.

ObjectDBX з'явився не так вже й давно, і його реєстрація на початку його існування відрізнялася від тієї, що використовується в версіях останнього часу.

Оскільки виклик ObjectDBX безпосередньо залежить від версії AutoCAD, спочатку визначимо версію:

Після отримання версії запущеного AutoCAD можна вже і намагатися викликати ObjectDBX:

Ну добре, сам інтерфейс отримано. А далі-то що? А далі ось що:

На даний момент найбільш цікаві методи Open і SaveAs (а не Save, як це не парадоксально). Прийшов час поговорити про те, як працює ObjectDBX, які у нього обмеження і як їх обходити.

Питання з відкриттям файлу можна навіть не піднімати:

# 40; vla - open odbx filename # 41;

А ось з обробкою і збереженням вже не все так очевидно.

Залишилося тільки одне: запам'ятати, що зберігається файл тільки в поточній версії і тільки через метод SaveAs:

Привіт Олексій, підкажіть будь ласка, а чи можливо використовуючи інтерфейс IAxDbDocument (або ObjectDBX) при роботі з неактивним документом, створити в цьому документі будь-якої примітив. Якщо можливо, то підкажіть як. У мене особисто не вийшло.

(Vla-AddCircle odbx (vlax-3D-point '(0 0 0)) 100)
; Помилка: ActiveX Server повернув помилку: невідоме ім'я: AddCircle

Якщо подивитися наведений вами список доступних методів і властивостей, отриманих в такий спосіб:
(Vlax-dump-Object odbx t),
То там є всього лише 8 доступних методів, і жоден з них не дозволяє створити примітив в неактивному документі.

Все вірно. Порівняйте:
(Vla-AddCircle odbx (vlax-3D-point '(0 0 0)) 100)
і
(Vla-AddCircle (vla-get-ModelSpace odbx) (vlax-3D-point '(0 0 0)) 100)
Примітив не може бути створений в документі. Створюваний примітив розташовується в якомусь просторі - моделі, листа, блоку ...

Да не за что Я тут теж з такою задачкою зіткнувся - мама не горюй. Якщо з'явиться гарантовано працююче рішення, поділюся

Хотілося б зробити невелике доповнення.
Стосується це можливості "відкриття через ObjectDBX заблокованого файлу". На даний момент я через vl-file-systime перевіряю доступність файлу на відкриття (функція повертає nil, якщо файл кимось відкритий). Якщо файл недоступний, то я його копіюю в% temp% і відкриваю вже звідти.
Не дуже витончено, зате працює. Поки, принаймні ...

Вітаю, Олексій.
Чи не підкажеш як правильно викликати vla-ZoomExtents після створення об'єкта в неактивному документі

(Vla-ZoomExtents (vlax-get-acad-object)) - применился тільки в поточному відкритому файлі
(Vla-zoomextents (vla-get-application (vla-get-activedocument (vlax-get-acad-object)))) - применился тільки в поточному відкритому файлі

(Vla-ZoomExtents (vla-get-ModelSpace odbx)); = ActiveX Server returned the error: unknown name: ZoomExtents [cc lang = "lisp"]

По-моєму, в неактивному документі це не зробити. Точно так же, як і не виконати в неактивному документі vla-purgeall.
А навіщо зумміровать неактивний документ?

Проектувальники захотіли автоматично обработивать dwg файли, отримані з Ревіт, для передачі суміжників, що працюють в Автокаде.
1.перекрасіть всі верстви в нейтрально сірий колір
2.переключіться в лист (layout)
3.отключіть всі верстви для кожного екрану (vplayer / freeze)
4.впісать в креслення в межі екрану (чому то приходячи з Ревіт креслення в межі екрану не вписаний)

схоже вирішувати за допомогою скрипта як в Reply # 4

>> Перефарбувати всі верстви ...
Не проблема
>> переключитися в лист (layout)
Переключитися або активувати, щоб він при відкритті був на екрані? І якщо переключитися, то на фіга? Через vla-get-block і так можна дістатися до опису блоку листа і працювати з ним як зі звичайним блоком
>> відключити всі шари для кожного екрану (vplayer / freeze)
Не впевнений, що подібне прокотить, але тим не менше: пройтися по всіх примітивів опису блоку листа, знайти ВЕ, отримати на них покажчики і далі з ними хімічити.
>> вписати в креслення в межі екрану (чому то приходячи з Ревіт креслення в межі екрану не вписаний)
В креслення або в ВЕ? Різниця трохи принципова. Якщо друге (і ВЕ вже існує) - то треба дивитися його масштаб, змінювати координати точки, на яку він вказує і т.д.
Оскільки переді мною подібних завдань ніколи не ставилося, готових рішень у мене немає

Олексій, спасибі за відповіді!
З перефарбою шарів я вже впорався
З темою роботи з неактивним документом зіткнувся вперше.
Мені здалося, що це більш правильний підхід (ніж через скрипти) якщо є необхідність обробки безлічі креслень.
Постановку задачі буду ще уточнювати ...

Олексій, ось хотілося б уточнити, чи можна в неактивному документі використовувати vl-cmdf? І якщо можна, то яка структура написання команди буде? Якщо я правильно розумію, то (vl-cmdf "_НазваніеКоманди") - така структура виклику команди буде працювати тільки в поточному кресленні?

Все правильно розумієте, vl-cmdf буде працювати тільки в активному документі. Не думаю, що спрацює навіть конструкція типу vla-SendCommand

Схожі статті