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

ADN Club => AutoCAD .NET API => Тема начата: Кирилл Никифоров от 15-03-2017, 08:34:41

Название: Как передать OdjctId.Null в Autolisp?
Отправлено: Кирилл Никифоров от 15-03-2017, 08:34:41
Здравствуйте!
Помогите начинающему.
Два вопроса:
1. Есть ли возможность вернуть из [LispFunction] в Autolisp ObjectId.Null? AutoCAD выдает ошибку eNullObjectId, а жаль.
2. Не нашел в SDK ничего, связанного с IdBuffer. С какой стороны к нему подойти, чтобы иметь возможность прочитать/записать в него данные?
Копию интернета уже сделал, ответов пока не нашел.
Название: Re: Как передать OdjctId.Null в Autolisp?
Отправлено: Дмитрий Загорулькин от 15-03-2017, 13:21:42
Давайте зайдем с другой стороны. Что должна вернуть Lisp-функция, если ObjectId.IsNull? В Lisp нет прямого эквивалента ObjectId.Null, поэтому и ошибка. По идее, функция должна вернуть NIL, в .NET его эквивалент - null.
Название: Re: Как передать OdjctId.Null в Autolisp?
Отправлено: Александр Ривилис от 15-03-2017, 13:24:21
2. Не нашел в SDK ничего, связанного с IdBuffer. С какой стороны к нему подойти, чтобы иметь возможность прочитать/записать в него данные?
Это что за IdBuffer?
Название: Re: Как передать OdjctId.Null в Autolisp?
Отправлено: Кирилл Никифоров от 15-03-2017, 13:25:28
А мне казалось, что есть. <EntityName: 0>
Название: Re: Как передать OdjctId.Null в Autolisp?
Отправлено: Кирилл Никифоров от 15-03-2017, 13:26:52
AcDbIdBuffer
В лиспе (0 . "IDBUFFER")
Очень полезная оказалась вещь. Активно использую... но пока только в лиспе.
Название: Re: Как передать OdjctId.Null в Autolisp?
Отправлено: Дмитрий Загорулькин от 15-03-2017, 13:27:45
А мне казалось, что есть. <EntityName: 0>
Ок, может быть и есть. Но лично я бы предпочел получить NIL вместо этого пустого ENAME.
Название: Re: Как передать OdjctId.Null в Autolisp?
Отправлено: Александр Ривилис от 15-03-2017, 13:29:46
AcDbIdBuffer
В лиспе (0 . "IDBUFFER")
Очень полезная оказалась вещь. Активно использую... но пока только в лиспе.
Это недокументированная вещь и поэтому использовать не рекомендую. Для него нет никакого API. И честно говоря не понимаю зачем его можно использовать.
Название: Re: Как передать OdjctId.Null в Autolisp?
Отправлено: Кирилл Никифоров от 15-03-2017, 13:30:17
Код - Auto/Visual Lisp [Выбрать]
  1. (setq *NullEntity* (cdr (assoc 330 (entget (namedobjdict)))))
и
Код - Auto/Visual Lisp [Выбрать]
  1. (defun idbmake (aCustomData)
  2.   (entmakex
  3.     (cons
  4.       (cons 0 "IDBUFFER")
  5.       (cons (cons 100 "AcDbIdBuffer")
  6.             aCustomData))))
Даннные в нем EntityNames с кодом 330
Название: Re: Как передать OdjctId.Null в Autolisp?
Отправлено: Кирилл Никифоров от 15-03-2017, 13:36:41
Я это обнаружил в документации по DXF в хелпе
http://help.autodesk.com/view/ACD/2017/ENU/?guid=GUID-7A243F2B-72D8-4C48-A29A-3F251B86D03F
Потестировал. И использую для сохранения наборов EntityNames.
Вот хотел попробовать пообщаться с IdBuffer через c#.
Название: Re: Как передать OdjctId.Null в Autolisp?
Отправлено: Кирилл Никифоров от 15-03-2017, 13:49:12
Цитировать
Ок, может быть и есть. Но лично я бы предпочел получить NIL вместо этого пустого ENAME.
Дык Nil - это пусто, а <EName: 0> значит, что объект был и был удален, и скорее всего не в этой сессии акада.
Я это дело использую именно для таких проверок. <EName: 0> часто образуются в xRecord и IdBuffer.
В лиспе <EName: 0> можно сравнить с другим <EName: 12345> с помощью eq, например.
Название: Re: Как передать OdjctId.Null в Autolisp?
Отправлено: Дмитрий Загорулькин от 15-03-2017, 13:58:20
Может быть, в каком-то контексте это и удобно, не спорю. Я себе представлял такой сценарий:
Код - Auto/Visual Lisp [Выбрать]
  1. (if (setq ename (my-super-puper-lisp-function-from-net))
  2.   (Alert "Ename получен, выполняем с ним какие-то действия")
  3.   (Alert "Ename не удалось получить, ничего не делаем")
  4. )
Название: Re: Как передать OdjctId.Null в Autolisp?
Отправлено: Александр Ривилис от 15-03-2017, 14:04:52
Кирилл Никифоров
Я бы рекомендовал заменить IDBUFFER на XRECORD, так как для него есть и документация  и API и в .NET и в lisp и в ObjectARX.
Название: Re: Как передать OdjctId.Null в Autolisp?
Отправлено: Владимир Шу от 15-03-2017, 16:28:08
Дык Nil - это пусто, а <EName: 0> значит, что объект был и был удален, и скорее всего не в этой сессии акада.
а если возвращать LispDataType.None (int 5000) ?
Название: Re: Как передать OdjctId.Null в Autolisp?
Отправлено: Кирилл Никифоров от 15-03-2017, 16:37:35
Александр, Дмитрий! Спасибо.

Получается, что это не вопросы у меня были, а лайф-хаки.  ;D
Жалко, что переход с лиспа на .net не получается плавным. Общего у них маловато.
Надо переписывать все целиком, да еще и структуру данных пересматривать.

PS. Тогда поделюсь опытом. Может, кому пригодится.
1. Сравнение с <EntityName: 0> перед вызовом entget позволяет в autolisp избежать прерывания выполнения кода.
2. IdBuffer отлично сохраняется в любом Dictionary, xDictionary. Данные в нем можно перезаписать в autolisp (не vla) без удаления самого буфера, в отличие от XRecord.
Название: Re: Как передать OdjctId.Null в Autolisp?
Отправлено: Кирилл Никифоров от 15-03-2017, 16:48:46
Цитировать
а если возвращать LispDataType.None (int 5000) ?

А на входе в лисп все равно будет nil. Или пусто.
Дело в том, что <EntityName: 0> не я создаю, они уже есть в данных, извлеченных из xRecord, например. И мне их надо прочитать.
И если они записаны с кодом LispDataType.ObjectId, то и читать их надо как EntityName.
Т.е. и в с# и в autolisp по отдельности проблем нет. А вот как передать такие данные из .net в лисп - вопрос.
Название: Re: Как передать OdjctId.Null в Autolisp?
Отправлено: Александр Ривилис от 15-03-2017, 17:48:52
А вот как передать такие данные из .net в лисп - вопрос.
Никак. Причем это не единственные данные, которые не передаются  lisp <-> C#
Название: Re: Как передать OdjctId.Null в Autolisp?
Отправлено: Кирилл Никифоров от 15-03-2017, 18:02:24
Цитировать
Никак. Причем это не единственные данные, которые не передаются  lisp <-> C#
Это - да... и символы никак, и с листами - беда...
Я наивно надеялся, что хоть на уровне основных DXF-ных данных совместимость обеспечена.  :'(
Значит, мы пойдем другим путем!

Спасибо!
Название: Re: Как передать OdjctId.Null в Autolisp?
Отправлено: Александр Ривилис от 15-03-2017, 18:18:12
DXF-список передать можно (по аналогии с тем, как это передаётся из/в ObjectARX), но придётся извращаться.
Название: Re: Как передать OdjctId.Null в Autolisp?
Отправлено: Кирилл Никифоров от 15-03-2017, 18:47:10
Цитировать
DXF-список передать можно (по аналогии с тем, как это передаётся из/в ObjectARX), но придётся извращаться.
У меня была надежда ускорить функции, используемые в лиспе, переписав их на c#. А с извращениями и неполной "совместимостью" быстрее не получится. Думаю, правильно будет разделить код на более крупные блоки. На лиспе оставить отлаживаемые алгоритмы, а отлаженные потихоньку перетаскивать под c#. И если писать какие-то лисп-функции на с#, то без аргументов. Результаты вычислений - только в Dictionary и XRecord. Где-то так.
Название: Re: Как передать OdjctId.Null в Autolisp?
Отправлено: Александр Ривилис от 15-03-2017, 19:32:31
Результаты вычислений - только в Dictionary и XRecord.
Результаты вычислений???
Название: Re: Как передать OdjctId.Null в Autolisp?
Отправлено: Кирилл Никифоров от 15-03-2017, 19:56:07
 8) Ну да, у нас это так называется.
В-основном, создание и ориентирование графов, поиск путей в них и нанесение на планы.
И разные другие расчетно-визуальные приблуды для проектировщиков.