Нужно с использованием AutoLISP или Visual LISP (...

Créé le : 15 avril 2026

Répondu en utilisant GPT-5.4 Thinking par Chat01

Question

Нужно с использованием AutoLISP или Visual LISP (AutoCAD 2021 (RU)) выбрать блок на чертеже и расставить в вершинах полилинии.
/не использовать в коде function STRINGP, CONSP, WHEN,
можно использовать в коде функции типа vla-, vlax- и подобные, которые есть
в стандартной библиотеке AutoLISP/.

Réflexion

Handling block selection and cancellation

I need to ensure that if the user cancels the selection, the process ends without duplication. If blkSel is empty, it indicates no selection, and I can still end the process smoothly. For cancellation, I shouldn’t show unnecessary messages, so I’ll filter out common exit signals. I’ll also ensure proper block insertion behavior, preserving rotation and space.

Handling block insertion with elevation data

Using vla-move works fine for copying blocks onto vertices without disturbing the original. I need to consider whether the user wants to keep the source block or just duplicate it at each vertex. For 3D, I’ll make sure to handle the elevation data in LWPOLYLINEs, including group 38. Great catch with incorporating elevation for 3D vertices!

Thought for 3m 36s

Réponse

Ниже — готовая команда AutoLISP/Visual LISP для AutoCAD 2021 (RU):

  • выбираете существующий блок на чертеже;
  • выбираете полилинию;
  • блок копируется во все вершины полилинии;
  • в коде не используются STRINGP, CONSP, WHEN.

Код работает с LWPOLYLINE и POLYLINE.
Копии сохраняют свойства исходного блока: имя, масштаб, угол, слой, атрибуты и т.д., потому что создаются через vla-Copy.

lisp
(vl-load-com) (defun _pt->3d (p /) (if (= (length p) 2) (list (car p) (cadr p) 0.0) (list (car p) (cadr p) (caddr p)) ) ) (defun _lwpoly-verts (e / d itm res elev p) (setq d (entget e)) (setq elev (cdr (assoc 38 d))) (if (null elev) (setq elev 0.0) ) (while d (setq itm (car d)) (if (= (car itm) 10) (progn (setq p (cdr itm)) (setq p (list (car p) (cadr p) elev)) (setq res (cons (trans p e 0) res)) ) ) (setq d (cdr d)) ) (reverse res) ) (defun _oldpoly-verts (e / n ed typ res p) (setq n (entnext e)) (while n (setq ed (entget n)) (setq typ (cdr (assoc 0 ed))) (if (= typ "SEQEND") (setq n nil) (progn (if (= typ "VERTEX") (progn (setq p (cdr (assoc 10 ed))) (if p (setq res (cons (trans (_pt->3d p) e 0) res)) ) ) ) (setq n (entnext n)) ) ) ) (reverse res) ) (defun _pline-verts (e / typ) (setq typ (cdr (assoc 0 (entget e)))) (if (= typ "LWPOLYLINE") (_lwpoly-verts e) (_oldpoly-verts e) ) ) (defun c:BLKVERTS (/ *error* acad doc blkSel blkEnt blkType blkObj basePt plSel plEnt plType verts pt newObj cnt) (vl-load-com) (defun *error* (msg) (if doc (vla-EndUndoMark doc) ) (if (and msg (/= msg "Function cancelled") (/= msg "quit / exit abort")) (princ (strcat "\nОшибка: " msg)) ) (princ) ) (setq acad (vlax-get-acad-object)) (setq doc (vla-get-ActiveDocument acad)) (vla-StartUndoMark doc) (setq blkSel (entsel "\nВыберите блок-образец: ")) (if blkSel (progn (setq blkEnt (car blkSel)) (setq blkType (cdr (assoc 0 (entget blkEnt)))) (if (= blkType "INSERT") (progn (setq plSel (entsel "\nВыберите полилинию: ")) (if plSel (progn (setq plEnt (car plSel)) (setq plType (cdr (assoc 0 (entget plEnt)))) (if (or (= plType "LWPOLYLINE") (= plType "POLYLINE")) (progn (setq verts (_pline-verts plEnt)) (if verts (progn (setq blkObj (vlax-ename->vla-object blkEnt)) (setq basePt (trans (_pt->3d (cdr (assoc 10 (entget blkEnt)))) blkEnt 0)) (setq cnt 0) (while verts (setq pt (car verts)) (setq newObj (vla-Copy blkObj)) (vla-Move newObj (vlax-3d-point basePt) (vlax-3d-point pt)) (setq cnt (1+ cnt)) (setq verts (cdr verts)) ) (princ (strcat "\nГотово. Размещено блоков: " (itoa cnt))) ) (princ "\nУ выбранной полилинии не найдены вершины.") ) ) (princ "\nВыбран не объект типа полилиния.") ) ) (princ "\nПолилиния не выбрана.") ) ) (princ "\nВыбран не блок.") ) ) (princ "\nБлок не выбран.") ) (vla-EndUndoMark doc) (princ) )

Как использовать:

  1. Сохраните код в файл, например BLKVERTS.lsp
  2. Загрузите через APPLOAD
  3. Введите команду:
    lisp
    BLKVERTS
  4. Выберите блок
  5. Выберите полилинию

Что важно:

  • для замкнутой полилинии блок ставится в каждую вершину без повторного дублирования первой точки в конце;
  • исходный выбранный блок не удаляется и не перемещается, создаются именно копии;
  • если у блока есть атрибуты, значения у копий будут такими же, как у исходного блока.

Если нужно, я могу сразу дать вторую версию, где:

  • исходный блок не копируется в вершину, совпадающую с его текущей точкой вставки;
  • или блоки ставятся с поворотом по направлению сегментов полилинии.

Partager cette Q&R