К основному содержимому
К каталогу

Проверка чертежа СПЗ

Линтер чертежа одной командой: двойные вставки блоков, датчики без адреса, пустые атрибуты, объекты на слое 0 и слои вне стандарта — LSP-команда с маркерами находок и листанием с зумом.

1. Что проверяем

Блок с тем же именем ближе допуска — почти всегда случайный копипаст: на печати не видно, а спецификация и расчёты завышены.

У блока по маске нет ни заполненного атрибута адреса, ни текстовой подписи формата «префикс + число + суффикс» в радиусе поиска.

Для организаций с атрибутным стандартом блоков: у каждого блока по маске перечисленные атрибуты существуют и непусты. Различаются «нет атрибута» и «пустой атрибут».

Динамические блоки сверяются по исходному (эффективному) имени.

В выпускаемом чертеже объектам на слое 0 не место. Отключите, если проверяете файл с чужой подложкой, начерченной на слое 0, — иначе находок будут сотни.

Слои вне стандарта

Маски допустимых слоёв через запятую или с новой строки; пусто — не проверять. Слои «0», Defpoints и слой маркеров допустимы всегда. Сообщаются только слои, на которых есть объекты в модели.

2. Маркеры находок

Находки печатаются в командную строку и обводятся кружками (не больше 200 — дальше только счёт). Повторный запуск смывает старые маркеры и ставит новые; вся серия откатывается одним U.

3. Скрипт

Показать текст LSP
;; ПоНорме (ponorme.ru) — проверка чертежа СПЗ одной командой.
;; ПРОВЕРКА прогоняет включённые проверки по модели: двойные вставки блоков,
;; блоки без адреса, атрибуты, слой 0, слои вне стандарта. Находки печатаются
;; в командную строку и обводятся кружками на слое ПРОВЕРКА (повторный
;; запуск обновляет маркеры). Загрузка: перетащить .lsp в чертёж или APPLOAD.
(defun pnrm:chk-layer (nm col)
  (if (not (tblsearch "LAYER" nm))
    (entmake (list (cons 0 "LAYER") (cons 100 "AcDbSymbolTableRecord")
                   (cons 100 "AcDbLayerTableRecord") (cons 2 nm) (cons 70 0) (cons 62 col)))))

;; кружок-маркер: счёт находок не ограничен, кружков — не больше лимита
(defun pnrm:chk-mark (p)
  (setq total (1+ total))
  (if (< (length marks) 200)
    (progn
      (entmake (list (cons 0 "CIRCLE") (cons 8 "ПРОВЕРКА") (cons 10 p) (cons 40 5.0)))
      (setq marks (cons p marks)))))

;; имя блока с учётом динамических (эффективное имя)
(defun pnrm:chk-bname (e / obj)
  (setq obj (vlax-ename->vla-object e))
  (if (vlax-property-available-p obj 'EffectiveName)
    (vla-get-EffectiveName obj) (vla-get-Name obj)))

;; значение атрибута тега без крайних пробелов; nil — атрибута нет
(defun pnrm:chk-attr (e tag / a ed r)
  (setq a (entnext e))
  (while (and a (= "ATTRIB" (cdr (assoc 0 (setq ed (entget a))))))
    (if (= tag (strcase (cdr (assoc 2 ed))))
      (setq r (vl-string-trim " " (cdr (assoc 1 ed)))))
    (setq a (entnext a)))
  r)

;; разбор подписи «префикс + число + суффикс» в номер, иначе nil
(defun pnrm:chk-parse (s / m i c ok)
  (if (and (> (strlen s) 0)
           (= "" (substr s 1 0))
           (= "" (substr s (- (strlen s) 0 -1))))
    (progn
      (setq m (substr s (1+ 0) (- (strlen s) 0)) i 1 ok T)
      (while (and ok (<= i (strlen m)))
        (setq c (ascii (substr m i 1)))
        (if (or (< c 48) (> c 57)) (setq ok nil))
        (setq i (1+ i)))
      (if ok (atoi m)))))

(defun c:ПРОВЕРКА (/ *error* doc marks total ss i e ed nm p v g has tbl txts rest lay dcnt acnt ecnt cnt0 bad tg)
  (vl-load-com)
  (setq doc (vla-get-ActiveDocument (vlax-get-acad-object)))
  (defun *error* (msg)
    (vl-catch-all-apply 'vla-EndUndoMark (list doc))
    (princ))
  (setq marks nil total 0)
  (vla-StartUndoMark doc)
  ;; смыть маркеры прошлого запуска
  (if (setq ss (ssget "_X" '((0 . "CIRCLE") (8 . "ПРОВЕРКА"))))
    (progn (setq i 0)
      (repeat (sslength ss) (entdel (ssname ss i)) (setq i (1+ i)))))
  (pnrm:chk-layer "ПРОВЕРКА" 1)
  (princ "\nПроверка чертежа:")
  ;; --- двойные вставки блоков: одно имя, точки ближе допуска ---
  (setq dcnt 0 tbl nil)
  (if (setq ss (ssget "_X" '((0 . "INSERT") (410 . "Model"))))
    (progn (setq i 0)
      (repeat (sslength ss)
        (setq e (ssname ss i) i (1+ i)
              nm (strcase (pnrm:chk-bname e))
              p (trans (cdr (assoc 10 (entget e))) e 0)
              g (assoc nm tbl))
        (if (and g (vl-some '(lambda (q) (< (distance q p) 1.0)) (cdr g)))
          (progn
            (setq dcnt (1+ dcnt))
            (pnrm:chk-mark p)
            (princ (strcat "\n  двойная вставка " nm " в " (rtos (car p) 2 1) ", " (rtos (cadr p) 2 1))))
          (if g (setq tbl (subst (cons nm (cons p (cdr g))) g tbl))
            (setq tbl (cons (list nm p) tbl)))))))
  (princ (strcat "\nДвойные вставки: " (itoa dcnt) "."))
  ;; --- блоки без адреса: ни заполненного атрибута, ни подписи рядом ---
  (setq acnt 0 txts nil)
  (if (setq ss (ssget "_X" '((0 . "TEXT") (410 . "Model"))))
    (progn (setq i 0)
      (repeat (sslength ss)
        (setq e (ssname ss i) i (1+ i) ed (entget e))
        (if (pnrm:chk-parse (cdr (assoc 1 ed)))
          (setq txts (cons (trans (cdr (assoc 10 ed)) e 0) txts))))))
  (if (setq ss (ssget "_X" '((0 . "INSERT") (410 . "Model"))))
    (progn (setq i 0)
      (repeat (sslength ss)
        (setq e (ssname ss i) i (1+ i) nm (pnrm:chk-bname e))
        (if (wcmatch (strcase nm) "ИП*,ДИП*,ИПР*")
          (progn
            (setq p (trans (cdr (assoc 10 (entget e))) e 0))
            (setq v (pnrm:chk-attr e "АДРЕС"))
            (setq has (and v (> (strlen v) 0)))
            (if (not has)
              (setq has (vl-some '(lambda (q) (< (distance q p) 10.0)) txts)))
            (if (not has)
              (progn
                (setq acnt (1+ acnt))
                (pnrm:chk-mark p)
                (princ (strcat "\n  без адреса: " nm " в " (rtos (car p) 2 1) ", " (rtos (cadr p) 2 1))))))))))
  (princ (strcat "\nБез адреса: " (itoa acnt) "."))
  ;; --- объекты на слое 0 (в своём чертеже им не место) ---
  (setq cnt0 0)
  (if (setq ss (ssget "_X" '((8 . "0") (410 . "Model"))))
    (progn (setq cnt0 (sslength ss) i 0)
      (repeat (sslength ss)
        (setq e (ssname ss i) i (1+ i) p (cdr (assoc 10 (entget e))))
        (if p (pnrm:chk-mark (trans p e 0))))))
  (princ (strcat "\nНа слое 0: " (itoa cnt0) " объектов."))
  (vla-EndUndoMark doc)
  (princ (strcat "\nИтого находок: " (itoa total)
                 "; маркеров на слое ПРОВЕРКА: " (itoa (length marks))
                 (if (> total (length marks)) " (лимит 200)" "") "."))
  (if marks
    (progn
      (setq rest (reverse marks))
      (while (and rest
                  (= "" (progn
                          (command "_.ZOOM" "_C" (trans (car rest) 0 1) 300.0)
                          (getstring "\n<Enter> — следующая находка, любой ввод — стоп: "))))
        (setq rest (cdr rest)))))
  (princ))

(princ "\nПоНорме: загружена команда ПРОВЕРКА.")
(princ)
Как подключить и пользоваться
  1. Разово: перетащите скачанный .lsp в окно чертежа — или команда ЗАГПРИЛ (_APPLOAD) → выбрать файл → «Загрузить».
  2. Навсегда: в том же окне APPLOAD добавьте файл в «Приложения, загружаемые с автозагрузкой» (Startup Suite).
  3. Наберите ПРОВЕРКА — команда без вопросов прогонит все включённые проверки и напечатает отчёт; находки обведены кружками на слое ПРОВЕРКА.
  4. Дальше Enter листает находки с зумом; любой другой ввод или Esc — стоп.
  5. Исправили — запустите команду снова: старые кружки смываются, отчёт пересчитывается. Перед выпуском листа отключите или заморозьте слой маркеров.
  6. Файл в кодировке ANSI (cp1251) — как принято для AutoLISP с русским текстом. nanoCAD загружает те же .lsp.

Справка

Назначение и исходные условия

Линтер чертежа СПЗ: одна LSP-команда прогоняет включённые проверки по модели и печатает отчёт, а находки обводит кружками на отдельном слое — как проверка кода у программистов, только для плана сигнализации. Повторный запуск смывает старые маркеры и пересчитывает отчёт, после отчёта находки листаются с зумом по Enter.

Правила настраиваются в форме и попадают в скрипт только включённые. Самое ценное — двойные вставки блоков: случайный копипаст датчика в ту же точку на печати не виден, но завышает спецификацию, ёмкость АКБ и число адресов; команда ловит такие пары по эффективному имени (динамические блоки не обманут) и совпадению точек с допуском. Блоки без адреса ищутся по маске имён: адресом считается заполненный атрибут с заданным тегом или подпись формата «префикс + число + суффикс» рядом — формат тот же, что в инструменте нумерации. Для организаций с атрибутным стандартом есть проверка обязательных атрибутов (различает «атрибута нет» и «атрибут пуст»), для стандарта слоёв — белый список масок; объекты на слое 0 отмечаются всегда, если правило включено.

Проверяется только то, что честно выводится из геометрии DWG: правил вида «устройство не подключено» или «извещатель вне помещения» линтер не обещает — в чужом чертеже линия связи неотличима от прочих отрезков. Дубли и пропуски самих адресов проверяет парная команда АДРЕС-ДУБЛИ из инструмента нумерации.

Частые вопросы

Что именно проверяется?

Пять правил, каждое отключаемо: двойные вставки одного блока в одной точке; блоки по маске без адреса (ни заполненного атрибута, ни подписи рядом); обязательные атрибуты существуют и непусты; объекты на слое 0; слои вне белого списка масок. Проверяется пространство модели.

Почему двойные вставки — первая проверка?

Блок, случайно вставленный дважды в одну точку, на печати не виден вообще: чертёж выглядит правильно, а спецификация, ёмкость АКБ и адреса считаются с лишним устройством. Ошибка всплывает только при монтаже. Команда ловит такие пары по совпадению эффективного имени и точки вставки с допуском.

Как команда понимает, что у блока есть адрес?

Адрес есть, если у блока заполнен атрибут с заданным тегом или в радиусе поиска найден однострочный текст формата «префикс + число + суффикс» — тот же формат, что в инструменте нумерации. Дубли и пропуски самих адресов ищет команда АДРЕС-ДУБЛИ из инструмента нумерации.

Как разбирать находки?

Каждая находка печатается в командной строке и обводится кружком на слое проверки (до 200 кружков, дальше — только счёт). После отчёта Enter листает находки с зумом. Исправили — запустите команду снова: старые кружки смоются, отчёт пересчитается.

Чего линтер не умеет?

Правил, требующих семантики проекта, в DWG не выводимой: «устройство не подключено к линии», «извещатель вне помещения», «кабельная линия не замкнута» — в чертеже линия связи и стена неотличимы от любых других отрезков. Такие проверки возможны только при жёстком стандарте слоёв и блоков.

Работает ли в AutoCAD LT и nanoCAD?

Полный AutoCAD и nanoCAD — да. AutoCAD LT 2023 и старше — нет (там нет AutoLISP); в LT 2024+ AutoLISP появился и, по справке Autodesk, используемые vla-/vlax-функции поддерживаются (внешние COM-объекты — нет), однако на LT работа не проверялась. Внешних зависимостей нет — только штатные функции чертежа.

Связанные расчёты

Нашли неточность — в формуле, числе или ссылке на пункт нормы? Напишите нам — проверим по первоисточнику и поправим. Замечания практиков уже не раз делали сервис точнее.

Данный сервис является справочным инструментом — окончательное решение принимается проектировщиком.