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

Créé le : 8 décembre 2025

Répondu en utilisant GPT-5.1 Thinking par Chat01

Question

Нужно с использованием AutoLISP или Visual LISP (AutoCAD 2021 (RU)) разделить отрезок
или полилинию на одинаковые сегменты, с помощью отрезков в точках деления длиной 100 мм,
на слое "divid" цвет 6, толщина 0.3. Запросить у пользователя длину сегмента.
(не использовать в коде function STRINGP и WHEN)
(не использовать в коде функции типа vlax-curve-p и подобные, которые отсутствует
в стандартной библиотеке AutoLISP)

Réflexion

Clarifying AutoLISP query for segmenting lines

The user needs an AutoLISP routine for AutoCAD 2021 in Russian. The requirement is to divide a line or polyline into equal segments and draw small 100mm segments at the division points, all on a specific layer with particular settings. The task should avoid advanced functions like vlax-curve-p and stick to basic AutoLISP features. I'll need to clarify whether the small segments should align with the original line.

Clarifying approach for markers in line segmentation

The user seems to want to add markers at division points along a line or polyline, but the markers need to be small, not just dividing the line into equal segments. I can't use vlax-curve-p or similar functions, so I'll avoid Visual LISP and stick with basic AutoLISP, exploring alternatives like the DIVIDE or MEASURE commands. But, they specifically want 100mm segments, so I'll need to rethink how to create those segments directly.

Choosing between DIVIDE and MEASURE commands

The user seems to want to divide the line or polyline into equal segments, but with a custom user-defined length. The MEASURE command is a good fit here because it allows setting the segment length directly. On the other hand, DIVIDE only divides into a fixed number of segments, which doesn't match the user’s request for a specific length.

User input and approach for segment placement

The user wants to specify segment lengths, so after they select the object, I’ll ask for a segment length (using getreal). With MEASURE, I can then place points along the object at the specified length. I'll use ssget "P" to access the newly created points, corresponding to the last command. This should work to achieve the required result!

Clarifying segment markers and layer setup

After the MEASURE command, I can use ssget "P" to fetch the newly created points. At each point, I'll extract coordinates and create small 100mm lines, oriented horizontally (using a constant direction like world X), since the exact orientation wasn't specified. Importantly, these markers need to be placed on the correct layer, "divid", with the specified color and lineweight, ensuring the layer exists beforehand.

Setting up layer with the correct attributes

If the "divid" layer doesn't exist, I'll create it with the proper attributes: color 6, lineweight 0.3mm, and a continuous line type. Lines created will be assigned to this "divid" layer, with color set by layer (BYLAYER) and lineweight set at the layer level. I’ll ensure the measure points are deleted.

Ensuring selection validation and error handling for lines or polylines

We need to handle the object selection carefully, ensuring it's either a line or polyline. If not, we'll prompt for a valid selection. Also, we'll check the object length to ensure it's appropriate for the MEASURE command. Afterward, we'll delete the created points using entdel or _.ERASE.

Ensuring proper MEASURE command handling

We need to ensure that we’re correctly passing the segment length to the MEASURE command while accounting for potential issues like the user entering a value too large for the object. If this occurs, we’ll handle nil selections gracefully. Using "_.MEASURE" works globally, but we could also check if localized versions may work on this particular environment; the underscore ensures compatibility with the English version of AutoCAD.

Clarifying the MEASURE command sequence

I'll use ".MEASURE" to ensure it works globally in AutoCAD, regardless of language. The syntax requires selecting the object and specifying the segment length—it seems using "(command ".MEASURE" ent "" seglen)" should work fine for measuring. However, I’ll ensure proper conversion from entity names. After MEASURE, the selection will contain the generated points.

Clarifying MEASURE syntax and approach

I need to ensure the right syntax: for "_.MEASURE", I call the entity with "" for the default and specify the segment length. I’ll avoid using VLAX functions and instead approximate the tangent direction by calculating the second point along the polyline or line segment. This approach makes it more intuitive.

Refining DIVSEG function and approach

The goal here is to divide a line or polyline into segments, creating 100 mm long lines at measured points. The approach involves using the "MEASURE" command with AutoLISP to generate division points. Then, for each point, a line segment is drawn, either horizontally or vertically, with a set line weight.

Ensuring layer creation and properties

I need to make sure the "divid" layer is correctly created using AutoLISP. While I could use entmake, I find using the -LAYER command simpler and more reliable, especially ensuring the proper properties like color and lineweight. I'll design the function to create or modify the layer with all required attributes.

Ensuring layer properties correctly

I'm focusing on ensuring the "divid" layer exists with the correct properties. For new layers, I'll use entmake to create it. If the layer already exists but with different properties, I'll update it using the -LAYER command for updates. This should comply with the requirement for layer color and lineweight.

Simplifying layer creation and entity handling in AutoLISP

I plan to simplify the layer creation process by using entmake to create the "divid" layer with the specified color and lineweight, only if it doesn't already exist. For each line, I'll set the correct properties to override layer settings. I'll also avoid using uncommon functions and stick to standard AutoLISP practices to ensure compatibility and simplicity.

Simplifying point selection and entity handling with AutoLISP

I’ll use (ssget "L") to select the last created objects after running the MEASURE command. This approach is simple and standard, as it captures all objects created by MEASURE (like points) in a selection set. By avoiding unnecessary error handling or complex commands, I’ll keep the code clean, ensuring it fits the desired constraints perfectly. I can now proceed with the final code using the function c:DIVID.

Thought for 2m 24s

Réponse

Вот вариант решения на «чистом» AutoLISP (без STRINGP, WHEN, vlax-curve-* и т.п.), для AutoCAD 2021 (RU).

Что делает программа

  • Просит выбрать отрезок или полилинию.
  • Просит ввести длину сегмента (расстояние между делениями вдоль объекта).
  • Командой MEASURE расставляет точки деления.
  • В каждой точке строит горизонтальный отрезок длиной 100 мм на слое "divid", цвет 6, толщина (lineweight) 0.30 мм.
  • Вспомогательные точки деления затем удаляются.

Код

Скопируйте этот код в файл *.lsp, загрузите через APPLOAD и вызовите команду DIVSEG.

lisp
;;; ---------------------------------------- ;;; Разделение отрезка/полилинии на части ;;; Делящие отрезки длиной 100 мм на слое "divid" ;;; Цвет 6, толщина (lineweight) 0.30 мм ;;; Команда: DIVSEG ;;; ---------------------------------------- (defun MakeDividLayer (/ lay) ;; Создаем слой "divid", если его нет (setq lay (tblsearch "LAYER" "divid")) (if (not lay) (entmake '( (0 . "LAYER") (2 . "divid") ; имя слоя (70 . 0) (62 . 6) ; цвет 6 (6 . "CONTINUOUS") ; тип линии (370 . 30) ; lineweight 0.30 мм (в сотых долях мм) ) ) ) ) (defun c:DIVSEG (/ ent ed type seglen ss n i pt halfLen oldCmdecho z) (princ "\nКоманда DIVSEG – деление отрезка/полилинии с делящими отрезками.") ;; Выбор объекта (setq ent (car (entsel "\nВыберите отрезок или полилинию: "))) (if ent (progn (setq ed (entget ent) type (cdr (assoc 0 ed))) (if (or (= type "LINE") (= type "LWPOLYLINE") (= type "POLYLINE")) (progn ;; Ввод длины сегмента (setq seglen (getreal "\nВведите длину сегмента (расстояние между делениями): ")) (if (and seglen (> seglen 0.0)) (progn ;; Слой для делящих отрезков (MakeDividLayer) ;; Скрываем эхо команд (setq oldCmdecho (getvar "CMDECHO")) (setvar "CMDECHO" 0) ;; Расставляем точки через заданный шаг (command "_.MEASURE" ent "" seglen) ;; Получаем созданные точки (последний набор объектов) (setq ss (ssget "L")) ;; Возвращаем CMDECHO (setvar "CMDECHO" oldCmdecho) (if ss (progn (setq n (sslength ss) i 0 halfLen 50.0) ; половина 100 мм (while (< i n) (setq pt (cdr (assoc 10 (entget (ssname ss i))))) (if pt (progn ;; Координата Z (если нет – берем 0) (setq z (if (caddr pt) (caddr pt) 0.0)) ;; Строим горизонтальный отрезок длиной 100 мм (entmake (list (cons 0 "LINE") (cons 8 "divid") ; слой (cons 62 6) ; цвет 6 (cons 370 30) ; lineweight 0.30 мм (cons 10 (list (- (car pt) halfLen) (cadr pt) z)) (cons 11 (list (+ (car pt) halfLen) (cadr pt) z)) ) ) ) ) (setq i (1+ i)) ) ;; Удаляем точки деления (command "_.ERASE" ss "") ) (princ "\nТочек деления не создано (возможно, длина сегмента больше длины объекта).") ) ) (princ "\nДлина сегмента должна быть положительным числом.") ) ) (princ "\nВыбранный объект не является отрезком или полилинией.") ) ) (princ "\nОбъект не выбран.") ) (princ) )

Как пользоваться

  1. Загрузите LISP-файл (APPLOAD).
  2. В командной строке введите: DIVSEG
  3. Выберите отрезок или полилинию.
  4. Введите длину сегмента (шаг деления вдоль объекта).

В результате вдоль объекта появятся короткие отрезки длиной 100 мм на слое "divid", цвет 6, lineweight 0.30 мм.

Partager cette Q&R