Тема: Как осуществить инверсию выбранных объектов?

Както сижу работаю ... и в голову влетела мысль "Почему в автокаде нету инверсии выбранных объектов? :/"
Вот решил в свободную минутку накидать
протестируйте! .........

(defun subtractionss(nabor1 nabor2 / id)
  (setq id 0)
  (while (> (sslength nabor1) id)
    (if (ssmemb (ssname nabor1 id) nabor2) (setq nabor2 (ssdel (ssname nabor1 id) nabor2)))
    (setq id (1+ id))
  );while
  (setq nabor2 nabor2)
)
(defun c:selinv(/ existss allss revss)
  (setq existss (ssget))
  (setq allss (ssget "_A"))
  (if (null existss) (setq existss (ssadd)))
  (if (null allss) (setq allss (ssadd)))
  (if (or (> (sslength existss) 0) (> (sslength allss) 0))
    (progn
      (if (setq revss (subtractionss existss allss))
        (progn
          (princ (strcat "\n " "Реверсия была выполнена" "\n"))
          (sssetfirst revss revss)
          (command "_regen")
        );progn
        (progn
          (princ (strcat "\n " "Ошибка: Возможно функция \"subtractionss\" небыла объявлена" "\n"))
        );progn
      );if
    );progn
    (princ (strcat "\n " "Ошибка: Нет объектов для инверсии" "\n"))
  );if
  (princ)
)

Re: Как осуществить инверсию выбранных объектов?

Команда работает, но есть пара предложений
По коду
1. Если объет в наборе, то ssdel удаляет его.
проверка (if (ssmemb ... лишняя
2. Возврат из программы достаточно указать переменную.
(setq nabor2 nabor2)-лишнее. Достаточно nabor2
3. Не понятна необходимость создания пустых наборов
  (if (null existss) (setq existss (ssadd)))
  (if (null allss) (setq allss (ssadd)))
Если ниже
(if (or (> (sslength existss) 0) (> (sslength allss) 0))
4. Зачем (princ (strcat "\n " "Ошибка ...))
если можно (princ "\nОшибка ...)
По выбору
Я бы у инверсированных объектов не включал ручки
(sssetfirst revss revss), а запоминал бы объекты в текущем наборе, сослаться на который можно с помощью опции _P (Previous) на запрос выбора объектов. Покрытие ручками занимает львиную долю времени. Когда объектов 30000 и более это очень даже чувствуется.
Вот вариант твоей программы с запоминанием в текущем наборе.

(defun c:si (/ existss allss revss)
  (defun subtractionss( / e1)
  (while (and existss (> (sslength existss) 0))
    (ssdel (setq e1 (ssname existss 0)) allss)
    (ssdel e1 existss))
  (if (zerop (sslength allss)) nil allss))
  (setq existss (ssget))
  (setq allss (ssget "_A"))
  (if (and allss (setq revss (subtractionss)))
    (progn
      (command "_.Select" revss "")
      (princ "\nИнверсия объектов выполнена.\n")
      (princ (sslength revss))
      (princ " объектов добавлены в текущий (previous) набор (_p).")
      );progn
    (princ "\nИнверсия объектов не выполнена"));if
    (princ))
(princ "\nНаберите SI")

Re: Как осуществить инверсию выбранных объектов?

С некоторыми предложениями согласен.
А вот что делает твой скрипт чтото я непонял
Команда написанная мной главным образом необходима для редактирования, чтобы легко можно было выполнить инверсию объектов.

Re: Как осуществить инверсию выбранных объектов?

Так она делает то же, только не покрывает инвертированные объекты ручками, а заносит их в текущий (последний, выполненный, previous) набор. Причины см. выше.
Выполни мой код, а затем например
_MOVE _P <указать точку> <указать точку>
_P как каз и ссылается на текущий набор.

Текущий (Previous)
Выбирает последний обработанный (текущий) набор объектов. Этот набор очищается операциями, удаляющими объекты из рисунка.
AutoCAD запоминает, в каком пространстве (листа или модели) был создан набор. При переключении пространства набор, выбранный в другом пространстве, игнорируется.