Тема: Как получить все координаты 3D-полилинии, не взрывая её?

Мне нужно получить все координаты 3D полилинии (не взрывая её). Дело в том, что 3D полилиния имеет такие параметры как smooth. Что делать если полилиния "сглажена"? Как в таком случае получить координаты прямых из которых состоит полилиния?

Re: Как получить все координаты 3D-полилинии, не взрывая её?

Чтобы получить все координаты всех вершин, вопользуйся

(vlax-safearray->list (vlax-variant-value (vla-get-Coordinates (vlax-ename->vla-object (car (entsel))))))

Возвращает одномерный список из координат вершин (3Д-точки для 3dpoly и 2Д-точки для lwpolyline). Если надо получить вершину со строго определенным номером

(vlax-safearray->list (vlax-variant-value (vla-get-Coordinate (vlax-ename->vla-object (car (entsel))) [b]Номер_вершины[/b])))

Re: Как получить все координаты 3D-полилинии, не взрывая её?

> Антон
Что-то вроде этого:

;; written by Fatty T.O.H.
;; group list by number
(defun group-by-num (lst num / ls ret)
  (if (= (rem (length lst) num ) 0)
    (progn
      (setq ls nil)
      (repeat (/ (length lst) num)
    (repeat num (setq ls
            (cons (car lst) ls)
          lst (cdr lst)))
    (setq ret (append ret (list (reverse ls)))
          ls nil)))
    )
ret
  )
;get polyline vertices
(defun get-vexs (pline_obj / verts)
      (setq verts (vlax-get pline_obj 'Coordinates)
        verts
          (cond
            ((wcmatch (vlax-get pline_obj 'Objectname )
                 "AcDb2dPolyline,AcDb3dPolyline")
             (group-by-num verts 3)
            )
            ((eq (vlax-get pline_obj 'Objectname )
                 "AcDbPolyline")
             (group-by-num verts 2)
            )
            (T nil)
          )
)
  )
;TesT:
(setq vertices_list
       (get-vexs
     (vlax-ename->vla-object
     (car (entsel "\n\t***\tSelect object : \t***\n")))))))))

~'J'~

Re: Как получить все координаты 3D-полилинии, не взрывая её?

В том-то всё и дело, что получить координаты вершин относительно просто... А вот как получить реальные координаты полилинии?
kpblc для теста можно начертить 3Д полилинию из 2 линий.

(vlax-safearray->list (vlax-variant-value (vla-get-Coordinates (vlax-ename->vla-object (car (entsel))))))

Выдаст ровно 3 координаты.
НО!!!
Если поставить Properties->fit/smooth->quadratic
То полилиния изменится, а код будет выдавать те же 3 координаты!
В этом и есть суть вопроса - как получить РЕАЛЬНЫЕ координаты полилинии?

Re: Как получить все координаты 3D-полилинии, не взрывая её?

Стоп. По тормозам. сглаживание полилинии не приводит к изменению координат ее вершин, об этом, по-моему, по всей документации говорится. Она ж вершина, куда ей деваться-то? А есть снять сглаживание, чего будет? Если вершина "съедет", как можно будет это объяснить? Так что вершина сидит как вкопанная, чего ей еще делать-то?
Или вопрос задан некорректно, и надо на самом деле определять не вершины, а некоторые точки, ближайшие к указанной?

Re: Как получить все координаты 3D-полилинии, не взрывая её?

> Антон
Что такое "реальные координаты полилинии"? Если ты ее "скруглил", то у тебя уже нет реальных вершин этой полилинии и единственный способ - это выполнить ее апроксимацию, т.е. в зависимости от параметра получать точку на полилинии.

Re: Как получить все координаты 3D-полилинии, не взрывая её?

Вопрос задан совершенно корретный:
"Как получить координаты прямых из которых состоит полилиния?"
Если полилинию взорвать - она, независимо от сглаживания, распадётся на набор прямых, который меня и интересует. Вопрос в том как найти координаты этих прямых без взрывания полилинии.

Re: Как получить все координаты 3D-полилинии, не взрывая её?

Все, теперь я перегрелся. Суть вопроса дошла.
Хотя с другой стороны, все равно вопрос не до конца не понятен (все равно, правда, я помочь не смогу) - как минимум шаг получения координат надо знать да направление, по которому получать эти координаты для каждого сегмента полилинии...
---
ИМХО
---
Пока писал, новые посты появились. Антон, ты уж определись, чего тебе надобно. Если ты знаешь начальную и конечную координату отрезка, ты сможешь получить координаты любой точки, принадлежащей этому отрезку.

Re: Как получить все координаты 3D-полилинии, не взрывая её?

(defun test (/ EN I LST)
  (setq    en (car (entsel))
    i  0
  ) ;_  setq
  (repeat (fix(vlax-curve-getEndParam en))
    (setq lst (cons (vlax-curve-getPointAtParam en i) lst)
      i   (1+ i)
    ) ;_  setq
  ) ;_  repeat
  lst
) ;_  defun
(test)

Re: Как получить все координаты 3D-полилинии, не взрывая её?

Евгений, я проверил Ваш код, но... Увы и ах... К сожалению он выдаёт набор точек на полилинии. Причем где-то посередине полилинии, а не от начала и до конца. Всё равно спасибо, вопрос остаётся открытым.

Re: Как получить все координаты 3D-полилинии, не взрывая её?

Извиняюсь... Сам дурак! Евгений Вы - Гений! Ваш код работает. Спасибо

Re: Как получить все координаты 3D-полилинии, не взрывая её?

> Антон
Ты рано радуешься, я тоже в свое время делал код
исходя из vlax-curve-getPointAtParam, посмотри
внимательно разницу для замкнутых и разомкнутых полилиний
~'J'~

Re: Как получить все координаты 3D-полилинии, не взрывая её?

Для теста написал следующий код:

(defun test (/ EN I LST temp)
  (setq  en (car (entsel))
  i  0
  ) ;_  setq
  (repeat (1+ (fix(vlax-curve-getEndParam en)))
    (setq lst (cons (vlax-curve-getPointAtParam en i) lst)
    i   (1+ i)
    ) ;_  setq
  ) ;_  repeat
  lst
  (Command "_.ERASE" en "")
  (Command "_.LINE")
  (foreach temp lst
    (Command temp)
    )
  (Command "")
)

По-моему всё работает.
Программа взрывает 3Дполилинию

Re: Как получить все координаты 3D-полилинии, не взрывая её?

AutoCAD Help: Developer Documentation/DXF Reference/ENTITIES Section/VERTEX:

Vertex group codes
100 Subclass marker (AcDbVertex)
100 Subclass marker (AcDb2dVertex or AcDb3dPolylineVertex)
10  Location point (in OCS when 2D, and WCS when 3D)
...
70 Vertex flags:
  1 = Extra vertex created by curve-fitting
  2 = Curve-fit tangent defined for this vertex. A curve-fit tangent direction of 0 may be omitted from DXF output but is significant if this bit is set
  4 = Not used
  8 = Spline vertex created by spline-fitting
16 = Spline frame control point
32 = 3D polyline vertex
64 = 3D polygon mesh
128 = Polyface mesh vertex
...

то есть все вершины 3D-Полилинии, у которых группа 70 содержит значение 40, являются точками на сглаженной кривой и располагаются как раз "...на концах прямых (то есть отрезков - VH.)...".
С помощью (entsel) выбрать 3D-Полилинию. С помощью (entnext) выбирать последовательно вершины. С помощью (entget) получать сведения об очередной вершине. С помощью (assoc) выбрать группу 70 и с помощью (logand) проанализировать ее значение. Ежели в состав значения входят и 32 и 8 (в сумме 40) - это "вершина" на сглаженной кривой, в противном случае можно эту вершину пропустить.
И никакого ActiveX?

Re: Как получить все координаты 3D-полилинии, не взрывая её?

> VH
Хорошее предложение (надо взять на заметку), только реализация несколько сложнее...

Re: Как получить все координаты 3D-полилинии, не взрывая её?

(defun C:3DPOLY_TRACE ()
 (if
  (progn
   (setq d (entget (setq e (car (entsel "\nSelect 3D Polyline: ")))))
   (apply 'and
    (mapcar 'equal
     (mapcar '(lambda (_code) (cdr (assoc _code d)))
      (list 0 70))
     (list "POLYLINE" 12))))
  (progn
   (setq point_list ())
   (while (equal (cdr (assoc 0 (setq d (entget (setq e (entnext e)))))) "VERTEX")
    (if (equal (logand (cdr (assoc 70 d)) 40) 40)
     (setq point_list (append point_list (list (cdr (assoc 10 d)))))))
   point_list ;здесь можно применить что-нибудь полезное к списку точек на сглаженной кривой
  )
  (prompt "\nThis is NOT a spline-fitted 3D Polyline.")))

Примечание: внешний вид сглаживания контролируется системными переменными SPLINETYPE и SPLINESEGS.

Re: Как получить все координаты 3D-полилинии, не взрывая её?

не получается получить координаты вершин 3d полилинии почему-то округляет

Re: Как получить все координаты 3D-полилинии, не взрывая её?

kpblc пишет:

Чтобы получить все координаты всех вершин, вопользуйся

(vlax-safearray->list (vlax-variant-value (vla-get-Coordinates (vlax-ename->vla-object (car (entsel))))))

Возвращает одномерный список из координат вершин (3Д-точки для 3dpoly и 2Д-точки для lwpolyline). Если надо получить вершину со строго определенным номером

(vlax-safearray->list (vlax-variant-value (vla-get-Coordinate (vlax-ename->vla-object (car (entsel))) [b]Номер_вершины[/b])))

не получается получить координаты вершин 3d полилинии почему-то округляет

Re: Как получить все координаты 3D-полилинии, не взрывая её?

reverendzah пишет:
kpblc пишет:

Чтобы получить все координаты всех вершин, вопользуйся

(vlax-safearray->list (vlax-variant-value (vla-get-Coordinates (vlax-ename->vla-object (car (entsel))))))

Возвращает одномерный список из координат вершин (3Д-точки для 3dpoly и 2Д-точки для lwpolyline). Если надо получить вершину со строго определенным номером

(vlax-safearray->list (vlax-variant-value (vla-get-Coordinate (vlax-ename->vla-object (car (entsel))) [b]Номер_вершины[/b])))

не получается получить координаты вершин 3d полилинии почему-то округляет

Добрый день. Тоже застопорился на этом на некоторое время. Ответ нашел на двгру от Алексея Кулика. То что отображается не значит что такие значения в памяти компьютера и есть. Чтобы проверить добавьте к коду выше перевод значения координаты в строку: (RTOS (CAR (vlax-safearray->list (vlax-variant-value (vla-get-Coordinates (vlax-ename->vla-object (car (entsel))))))) 2 2) можно вывести результат до 10 знаков после точки.