Тема: LISP.Выделение объектов в области контура

Две команды для выделения объектов путем указания существующего контура.
В качестве контура могут выступать сплайны, полилинии, дуги, круги, элипсы.
Подобные темы возникали здесь
http://dwg.ru/forum/viewtopic.php?t=10187
https://www.caduser.ru/forum/topic36384.html

;|
 Файл: SelectContour.lsp
 Команды: SCWP; SCCP
Выделение объектов путем указания существующего контура.
В качестве контура могут выступать сплайны, полилинии, дуги, круги, элипсы.
Контур должен быть выпуклым.
Две команды:
SCWP - выбирает объекты рамкой многоугольника
SCCP - выбирает объекты секрамкой многоугольника
Макрос для кнопки: ^C^C(load "SelectContour");SCWP
                   ^C^C(load "SelectContour");SCCP
Автор: Владимир Азарко (VVA) 2007 г.
|;
;Opt - "_WP" or "_CP"
(defun SelectContour ( opt / en ss lst)
(defun  lib:pt_extents (vlist / tmp)
(setq tmp (mapcar '(lambda (x) (vl-remove-if 'null x))
 (mapcar '(lambda (what) (mapcar '(lambda (x) (nth what x)) vlist))
 '(0 1 2))));_setq
  (list (mapcar '(lambda(x)(apply 'min x)) tmp)(mapcar '(lambda(x)(apply 'max x)) tmp)))
(defun lib:IsPtInView (pt / VCTR Y_Len SSZ X_Pix Y_Pix X_Len Lc Uc)
(setq pt (trans pt 0 1))
(setq VCTR (getvar "VIEWCTR") Y_Len (getvar "VIEWSIZE")
   SSZ (getvar "SCREENSIZE")
   X_Pix (car SSZ) Y_Pix (cadr SSZ)
   X_Len (* (/ X_Pix Y_Pix) Y_Len)
   Lc (polar VCTR (dtr 180.0) (* 0.5 X_Len))
   Uc (polar Lc 0.0 X_Len)
   Lc (polar Lc (dtr 270.0) (* 0.5 Y_Len))
   Uc (polar Uc (dtr 90.0) (* 0.5 Y_Len)))
(if (and (> (car pt) (car Lc))(< (car pt) (car Uc))
    (> (cadr pt) (cadr Lc))(< (cadr pt) (cadr Uc)))
   T nil))
(defun lib:Zoom2Lst( vlist / bl tr Lst OS)
(setq   Lst (lib:pt_extents vlist) bl (car Lst) tr (cadr Lst))
(if (not (and (lib:IsPtInView bl) (lib:IsPtInView tr)))
(progn  (setq OS (getvar "OSMODE"))(setvar "OSMODE" 0)
(command "_.Zoom" "_Window" (trans bl 0 1)(trans tr 0 1)
   "_.Zoom" "0.95x")
(setvar "OSMODE" OS) T) NIL))
(defun TraceObject (obj / typlst typ TracePline TraceACE TraceLine
                         TraceSpline TraceType1Pline
                          TraceType23Pline)
    (defun ZClosed (lst)
    (if (and (vlax-curve-isClosed obj)
         (not(equal (car lst)(last lst) 1e-6)))
      (append lst (list (car lst)))
      lst))
  (defun TracePline (obj / param endparam anginc tparam pt blg
                           ptlst delta inc arcparam flag)
    (setq param (vlax-curve-getStartParam obj)
          endparam (vlax-curve-getEndParam obj)
          anginc (* pi (/ 7.5 180.0)))
    (setq tparam param)
      (while (<= param endparam)
        (setq pt (vlax-curve-getPointAtParam obj param))
        (if (not (equal pt (car ptlst) 1e-12))
          (setq ptlst (cons pt ptlst)))
        (if  (and (/= param endparam)
            (setq blg (abs (vlax-invoke obj 'GetBulge param)))
            (/= 0 blg))
          (progn
            (setq delta (* 4 (atan blg)) ;included angle
                  inc (/ 1.0 (1+ (fix (/ delta anginc))))
                  arcparam (+ param inc))
            (while (< arcparam (1+ param))
              (setq pt (vlax-curve-getPointAtParam obj arcparam)
                    ptlst (cons pt ptlst)
                    arcparam (+ inc arcparam))))
        )
        (setq param (1+ param)))
    (if (and (apply 'and ptlst)
        (> (length ptlst) 1))
     (ZClosed (reverse ptlst)))) ;end
  (defun TraceACE (obj / startparam endparam anginc
                         delta div inc pt ptlst)
    (setq startparam (vlax-curve-getStartParam obj)
          endparam (vlax-curve-getEndParam obj)
          anginc (* pi (/ 5.0 180.0)))
    (if (equal endparam (* pi 2) 1e-12)
      (setq delta endparam)
      (setq delta (NormalAngle (- endparam startparam))))
    (setq div (1+ (fix (/ delta anginc)))
          inc (/ delta div))
    (while (or
        (< startparam endparam)
        (equal startparam endparam 1e-12))
      (setq pt (vlax-curve-getPointAtParam obj startparam)
            ptlst (cons pt ptlst)
            startparam (+ inc startparam)))
    (reverse ptlst)) ;end
  (defun TraceLine (obj)(list (vlax-get obj 'StartPoint)
        (vlax-get obj 'EndPoint)))
  (defun TraceSpline (obj / startparam endparam ncpts inc param
                            fd ptlst pt1 pt2 ang1 ang2 a)
    (setq startparam (vlax-curve-getStartParam obj)
          endparam (vlax-curve-getEndParam obj)
          ncpts (vlax-get obj 'NumberOfControlPoints)
          inc (/ (- endparam startparam) (* ncpts 7))
          param (+ inc startparam)
          fd (vlax-curve-getfirstderiv obj param)
          ptlst (cons (vlax-curve-getStartPoint obj) ptlst))
    (while (< param endparam)
      (setq pt1 (vlax-curve-getPointAtParam obj param)
            ang1 fd
            param (+ param inc)
            pt2 (vlax-curve-getPointAtParam obj param)
            fd (vlax-curve-getfirstderiv obj param)
            ang2 fd
            a (abs (3d_angw1w2 ang1 ang2)))
      (if (> a 0.00218166)(setq ptlst (cons pt1 ptlst))))
    (if (not (equal
          (setq pt1 (vlax-curve-getEndPoint obj)) (car ptlst) 1e-8))
      (setq ptlst (cons pt1 ptlst)))
    (reverse ptlst)) ;end
  (defun TraceType1Pline (obj / ptlst objlst lst)
    (setq ptlst (list (vlax-curve-getStartPoint obj))
          objlst (vlax-invoke obj 'Explode))
    (foreach x objlst
      (setq lst (TraceACE x))
      (if (not (equal (car lst) (last ptlst) 1e-8))
        (setq lst (reverse lst)))
      (setq ptlst (append ptlst (cdr lst)))
      (vla-delete x))(ZClosed  ptlst)) ;end
  (defun TraceType23Pline (obj / objlst ptlst lastpt)
    (setq objlst (vlax-invoke obj 'Explode)
          lastpt (vlax-get (last objlst) 'EndPoint))
    (foreach x objlst
      (setq ptlst (cons (vlax-get x 'StartPoint) ptlst))
      (vla-delete x))(ZClosed (reverse (cons lastpt ptlst)))) ;end
  (defun Trace3DPline (obj / coord ptlst)
    (setq coord (vlax-get obj 'Coordinates))
    (repeat (/ (length coord) 3)
      (setq ptlst (cons (list (car coord) (cadr coord)(caddr coord)) ptlst))
      (setq coord (cdddr coord)))(ZClosed (reverse ptlst))) ;end
(defun NormalAngle (a)(if (numberp a)(angtof (angtos a 0 14) 0)))
(defun 3d_angw1w2 (Wekt1 Wekt2 / CosA)
 (if (equal (setq CosA (/ (apply '+ (mapcar '* Wekt1 Wekt2))
              (distance '(0 0 0) Wekt1) (distance '(0 0 0) Wekt2))) -1.0 1e-6)
  Pi
  (if (equal CosA 0.0 1e-6) (* 0.5 PI)(atan (sqrt (- 1 (* CosA CosA))) CosA))))
  (setq typlst '("AcDb2dPolyline" "AcDbPolyline" "AcDb3dPolyline" "AcDbCircle"
         "AcDbArc" "AcDbEllipse" "AcDbSpline" "AcDbLine"))
  (or (eq (type obj) 'VLA-OBJECT)
    (setq obj (vlax-ename->vla-object obj)))
  (setq typ (vlax-get obj 'ObjectName))
  (if (vl-position typ typlst)
    (cond ((or (eq typ "AcDb2dPolyline") (eq typ "AcDbPolyline"))
      (cond ((or
               (not (vlax-property-available-p obj 'Type))
               (= 0 (vlax-get obj 'Type)))
              (TracePline obj))
            ((or (= 3 (vlax-get obj 'Type)) (= 2 (vlax-get obj 'Type)))
              (TraceType23Pline obj))
            ((= 1 (vlax-get obj 'Type))
              (TraceType1Pline obj))))
       ((eq typ "AcDbLine")(TraceLine obj))
       ((or (eq typ "AcDbCircle") (eq typ "AcDbArc") (eq typ "AcDbEllipse"))
         (TraceACE obj))
       ((eq typ "AcDbSpline")(TraceSpline obj))
       ((eq typ "AcDb3dPolyline")(Trace3DPline obj))
    )))
(vl-load-com)
  (setq en (car(entsel "\nУкажите контур: ")))
  (if (and en (wcmatch (cdr(assoc 0 (entget en))) "*POLYLINE,SPLINE,CIRCLE,ARC,ELLIPSE"))
    (progn
      (setq lst (TraceObject (vlax-ename->vla-object en)))
      (lib:Zoom2Lst lst);_Гарантированно полилиния на экране
      (setq lst (mapcar '(lambda(x)(trans x 0 1)) lst))
      (setq lst (mapcar '(lambda(x)(list (car x)(cadr x))) lst))
(if (setq ss (ssget opt lst))(SSSETFIRST ss ss))
(setq ss nil)))(princ))
;_Select Contour Window Polygon
(defun C:SCWP ()(SelectContour "_WP"))
;_Select Contour Crossing Polygon
(defun C:SCCP ()(SelectContour "_CP"))
(princ "\nНаберите в командной строке SCWP или SCCP")

Re: LISP.Выделение объектов в области контура

При выборе в круге текста пишет
; ошибка: no function definition: DTR

Re: LISP.Выделение объектов в области контура

> gest
Спасибо. Исправил

(defun SelectContour ( opt / en ss lst)
(defun DTR (a)(* pi (/ a 180.0)))
(defun  lib:pt_extents (vlist / tmp)
(setq tmp (mapcar '(lambda (x) (vl-remove-if 'null x))
 (mapcar '(lambda (what) (mapcar '(lambda (x) (nth what x)) vlist))
 '(0 1 2))));_setq
  (list (mapcar '(lambda(x)(apply 'min x)) tmp)(mapcar '(lambda(x)(apply 'max x)) tmp)))
(defun lib:IsPtInView (pt / VCTR Y_Len SSZ X_Pix Y_Pix X_Len Lc Uc)
(setq pt (trans pt 0 1))
(setq VCTR (getvar "VIEWCTR") Y_Len (getvar "VIEWSIZE")
   SSZ (getvar "SCREENSIZE")
   X_Pix (car SSZ) Y_Pix (cadr SSZ)
   X_Len (* (/ X_Pix Y_Pix) Y_Len)
   Lc (polar VCTR (dtr 180.0) (* 0.5 X_Len))
   Uc (polar Lc 0.0 X_Len)
   Lc (polar Lc (dtr 270.0) (* 0.5 Y_Len))
   Uc (polar Uc (dtr 90.0) (* 0.5 Y_Len)))
(if (and (> (car pt) (car Lc))(< (car pt) (car Uc))
    (> (cadr pt) (cadr Lc))(< (cadr pt) (cadr Uc)))
   T nil))
(defun lib:Zoom2Lst( vlist / bl tr Lst OS)
(setq   Lst (lib:pt_extents vlist) bl (car Lst) tr (cadr Lst))
(if (not (and (lib:IsPtInView bl) (lib:IsPtInView tr)))
(progn  (setq OS (getvar "OSMODE"))(setvar "OSMODE" 0)
(command "_.Zoom" "_Window" (trans bl 0 1)(trans tr 0 1)
   "_.Zoom" "0.95x")
(setvar "OSMODE" OS) T) NIL))
(defun TraceObject (obj / typlst typ TracePline TraceACE TraceLine
                         TraceSpline TraceType1Pline
                          TraceType23Pline)
    (defun ZClosed (lst)
    (if (and (vlax-curve-isClosed obj)
       (not(equal (car lst)(last lst) 1e-6)))
      (append lst (list (car lst)))
      lst))
  (defun TracePline (obj / param endparam anginc tparam pt blg
                           ptlst delta inc arcparam flag)
    (setq param (vlax-curve-getStartParam obj)
          endparam (vlax-curve-getEndParam obj)
          anginc (* pi (/ 7.5 180.0)))
    (setq tparam param)
      (while (<= param endparam)
        (setq pt (vlax-curve-getPointAtParam obj param))
        (if (not (equal pt (car ptlst) 1e-12))
          (setq ptlst (cons pt ptlst)))
        (if  (and (/= param endparam)
            (setq blg (abs (vlax-invoke obj 'GetBulge param)))
            (/= 0 blg))
          (progn
            (setq delta (* 4 (atan blg)) ;included angle
                  inc (/ 1.0 (1+ (fix (/ delta anginc))))
                  arcparam (+ param inc))
            (while (< arcparam (1+ param))
              (setq pt (vlax-curve-getPointAtParam obj arcparam)
                    ptlst (cons pt ptlst)
                    arcparam (+ inc arcparam))))
        )
        (setq param (1+ param)))
    (if (and (apply 'and ptlst)
        (> (length ptlst) 1))
     (ZClosed (reverse ptlst)))) ;end
  (defun TraceACE (obj / startparam endparam anginc
                         delta div inc pt ptlst)
    (setq startparam (vlax-curve-getStartParam obj)
          endparam (vlax-curve-getEndParam obj)
          anginc (* pi (/ 5.0 180.0)))
    (if (equal endparam (* pi 2) 1e-12)
      (setq delta endparam)
      (setq delta (NormalAngle (- endparam startparam))))
    (setq div (1+ (fix (/ delta anginc)))
          inc (/ delta div))
    (while (or
        (< startparam endparam)
        (equal startparam endparam 1e-12))
      (setq pt (vlax-curve-getPointAtParam obj startparam)
            ptlst (cons pt ptlst)
            startparam (+ inc startparam)))
    (reverse ptlst)) ;end
  (defun TraceLine (obj)(list (vlax-get obj 'StartPoint)
        (vlax-get obj 'EndPoint)))
  (defun TraceSpline (obj / startparam endparam ncpts inc param
                            fd ptlst pt1 pt2 ang1 ang2 a)
    (setq startparam (vlax-curve-getStartParam obj)
          endparam (vlax-curve-getEndParam obj)
          ncpts (vlax-get obj 'NumberOfControlPoints)
          inc (/ (- endparam startparam) (* ncpts 7))
          param (+ inc startparam)
          fd (vlax-curve-getfirstderiv obj param)
          ptlst (cons (vlax-curve-getStartPoint obj) ptlst))
    (while (< param endparam)
      (setq pt1 (vlax-curve-getPointAtParam obj param)
            ang1 fd
            param (+ param inc)
            pt2 (vlax-curve-getPointAtParam obj param)
            fd (vlax-curve-getfirstderiv obj param)
            ang2 fd
            a (abs (3d_angw1w2 ang1 ang2)))
      (if (> a 0.00218166)(setq ptlst (cons pt1 ptlst))))
    (if (not (equal
          (setq pt1 (vlax-curve-getEndPoint obj)) (car ptlst) 1e-8))
      (setq ptlst (cons pt1 ptlst)))
    (reverse ptlst)) ;end
  (defun TraceType1Pline (obj / ptlst objlst lst)
    (setq ptlst (list (vlax-curve-getStartPoint obj))
          objlst (vlax-invoke obj 'Explode))
    (foreach x objlst
      (setq lst (TraceACE x))
      (if (not (equal (car lst) (last ptlst) 1e-8))
        (setq lst (reverse lst)))
      (setq ptlst (append ptlst (cdr lst)))
      (vla-delete x))(ZClosed  ptlst)) ;end
  (defun TraceType23Pline (obj / objlst ptlst lastpt)
    (setq objlst (vlax-invoke obj 'Explode)
          lastpt (vlax-get (last objlst) 'EndPoint))
    (foreach x objlst
      (setq ptlst (cons (vlax-get x 'StartPoint) ptlst))
      (vla-delete x))(ZClosed (reverse (cons lastpt ptlst)))) ;end
  (defun Trace3DPline (obj / coord ptlst)
    (setq coord (vlax-get obj 'Coordinates))
    (repeat (/ (length coord) 3)
      (setq ptlst (cons (list (car coord) (cadr coord)(caddr coord)) ptlst))
      (setq coord (cdddr coord)))(ZClosed (reverse ptlst))) ;end
(defun NormalAngle (a)(if (numberp a)(angtof (angtos a 0 14) 0)))
(defun 3d_angw1w2 (Wekt1 Wekt2 / CosA)
 (if (equal (setq CosA (/ (apply '+ (mapcar '* Wekt1 Wekt2))
        (distance '(0 0 0) Wekt1) (distance '(0 0 0) Wekt2))) -1.0 1e-6)
  Pi
  (if (equal CosA 0.0 1e-6) (* 0.5 PI)(atan (sqrt (- 1 (* CosA CosA))) CosA))))
  (setq typlst '("AcDb2dPolyline" "AcDbPolyline" "AcDb3dPolyline" "AcDbCircle"
     "AcDbArc" "AcDbEllipse" "AcDbSpline" "AcDbLine"))
  (or (eq (type obj) 'VLA-OBJECT)
    (setq obj (vlax-ename->vla-object obj)))
  (setq typ (vlax-get obj 'ObjectName))
  (if (vl-position typ typlst)
    (cond ((or (eq typ "AcDb2dPolyline") (eq typ "AcDbPolyline"))
      (cond ((or
               (not (vlax-property-available-p obj 'Type))
               (= 0 (vlax-get obj 'Type)))
              (TracePline obj))
            ((or (= 3 (vlax-get obj 'Type)) (= 2 (vlax-get obj 'Type)))
              (TraceType23Pline obj))
            ((= 1 (vlax-get obj 'Type))
              (TraceType1Pline obj))))
       ((eq typ "AcDbLine")(TraceLine obj))
       ((or (eq typ "AcDbCircle") (eq typ "AcDbArc") (eq typ "AcDbEllipse"))
         (TraceACE obj))
       ((eq typ "AcDbSpline")(TraceSpline obj))
       ((eq typ "AcDb3dPolyline")(Trace3DPline obj))
    )))
(vl-load-com)
  (setq en (car(entsel "\nУкажите контур: ")))
  (if (and en (wcmatch (cdr(assoc 0 (entget en))) "*POLYLINE,SPLINE,CIRCLE,ARC,ELLIPSE"))
    (progn
      (setq lst (TraceObject (vlax-ename->vla-object en)))
      (lib:Zoom2Lst lst);_Гарантированно полилиния на экране
      (setq lst (mapcar '(lambda(x)(trans x 0 1)) lst))
      (setq lst (mapcar '(lambda(x)(list (car x)(cadr x))) lst))
(if (setq ss (ssget opt lst))(SSSETFIRST ss ss))
(setq ss nil)))(princ))
;_Select Contour Window Polygon
(defun C:SCWP ()(SelectContour "_WP"))
;_Select Contour Crossing Polygon
(defun C:SCCP ()(SelectContour "_CP"))
(princ "\nНаберите в командной строке SCWP или SCCP")

Re: LISP.Выделение объектов в области контура

> VVA
Если бы не ограничение по выпуклости контура можно было бы попробовать. Но имеется граница вокруг дороги и нужно выбрать блоки попадающие в эту границу, а она как раз не выпуклая. Если получится снять ограничение по контуру обязательно использую.

Re: LISP.Выделение объектов в области контура

> Valery Brelovsky
Ограничение по выпуклости накладываю не я, а ssget (автокадовкий выбор примитивов). Так что снять не получится :( Единственный выход - разбить невыпуклый многоуголиник на несколько выпуклых, но пока не ясен алгоритм

Re: LISP.Выделение объектов в области контура

То же самое, но с использованием Экспрессов и без проверки попадания контура на экран...

(setq
 opt "WP" ; способ выбора..
 fuzz 0.5 ; точность проверки..
 ss (ssget "WP" (ACET-GEOM-OBJECT-POINT-LIST (car (entsel)) fuzz))
 )

Кстати, объясните мне, в чем проблема с невыпуклыми контурами выбора? Контуром выбора, может быть любой несамопересекающийся многоугольник. Или я ошибаюсь?

Re: LISP.Выделение объектов в области контура

Кстати, объясните мне, в чем проблема с невыпуклыми контурами выбора? Контуром выбора, может быть любой несамопересекающийся многоугольник. Или я ошибаюсь?

Да нет, вроде, не ошибаешься.
Только вот что замечено, что для режима WP иногда ssget выбирает не все объекты, касающиеся одним концом контура, может это только для 3DPoly?

Re: LISP.Выделение объектов в области контура

> KAI
Это обычный вопрос с точностью - если объект касается контура, можно ли гарантировать, что он не выглядывает наружу? Тем более, если контур 3DPoly, то ее проекция добавляет ошибку...

Re: LISP.Выделение объектов в области контура

Наверное, вот и приходится для гарантии офсетить точки контура с небольшим смещением.

Re: LISP.Выделение объектов в области контура

Замечательно!
Но, всегда хочется большего.
Не могли бы вы дописать "выбор секущей рамкой" чтобы далее - copy, точка вставки, extrim. А если еще и запрос об масштабе вставки то вообще замечательно особенно для машиностроителей.

Re: LISP.Выделение объектов в области контура

> jonas
Опиши поподробнее что надо сделать

Re: LISP.Выделение объектов в области контура

> VVA
Вообще то я хочу того что уже существует в программах для машиностроителей а имеено делать выноски. Не хочу ради этого ставить другую прогу потому что спец-программы как правило слишком специализированны. Автокад универсален и это главное. Можно настроить как хочешь, под любой стандарт и свой вкус.
Для тог чтобы сделать выноску нужно:
- обозначить фрагмент чертежа кругом, элипсом, плинией и т.д.
- скопировать этот фрагмент вместе с кругом, ...
  секущей рамкой,
- вставить в "чистое поле",
- увеличить масштаб (по запросу),
- обрезать линии выступающие за пределы круга, ... .

Re: LISP.Выделение объектов в области контура

VVA,
Подскажите пожалуйста, у меня при вставке лиспа в автокад в командной строке выдается следющее сообщение:
[FONT=Optima]Желтый ; ошибка: неверно сформирванный список на входе[/FONT]
а лисп ваш просто отличная вещь! давно искал его, но увы  :( не работает.

Re: LISP.Выделение объектов в области контура

Исправить #3 я уже не могу. Бери отсюда

(defun SelectContour ( opt / en ss lst)
(defun DTR (a)(* pi (/ a 180.0)))
(defun  lib:pt_extents (vlist / tmp)
(setq tmp (mapcar '(lambda (x) (vl-remove-if 'null x))
 (mapcar '(lambda (what) (mapcar '(lambda (x) (nth what x)) vlist))
 '(0 1 2))));_setq
  (list (mapcar '(lambda(x)(apply 'min x)) tmp)(mapcar '(lambda(x)(apply 'max x)) tmp)))
(defun lib:IsPtInView (pt / VCTR Y_Len SSZ X_Pix Y_Pix X_Len Lc Uc)
(setq pt (trans pt 0 1))
(setq VCTR (getvar "VIEWCTR") Y_Len (getvar "VIEWSIZE")
   SSZ (getvar "SCREENSIZE")
   X_Pix (car SSZ) Y_Pix (cadr SSZ)
   X_Len (* (/ X_Pix Y_Pix) Y_Len)
   Lc (polar VCTR (dtr 180.0) (* 0.5 X_Len))
   Uc (polar Lc 0.0 X_Len)
   Lc (polar Lc (dtr 270.0) (* 0.5 Y_Len))
   Uc (polar Uc (dtr 90.0) (* 0.5 Y_Len)))
(if (and (> (car pt) (car Lc))(< (car pt) (car Uc))
    (> (cadr pt) (cadr Lc))(< (cadr pt) (cadr Uc)))
   T nil))
(defun lib:Zoom2Lst( vlist / bl tr Lst OS)
(setq   Lst (lib:pt_extents vlist) bl (car Lst) tr (cadr Lst))
(if (not (and (lib:IsPtInView bl) (lib:IsPtInView tr)))
(progn  (setq OS (getvar "OSMODE"))(setvar "OSMODE" 0)
(command "_.Zoom" "_Window" (trans bl 0 1)(trans tr 0 1)
   "_.Zoom" "0.95x")
(setvar "OSMODE" OS) T) NIL))
(defun TraceObject (obj / typlst typ TracePline TraceACE TraceLine
                         TraceSpline TraceType1Pline
                          TraceType23Pline)
    (defun ZClosed (lst)
    (if (and (vlax-curve-isClosed obj)
       (not(equal (car lst)(last lst) 1e-6)))
      (append lst (list (car lst)))
      lst))
  (defun TracePline (obj / param endparam anginc tparam pt blg
                           ptlst delta inc arcparam flag)
    (setq param (vlax-curve-getStartParam obj)
          endparam (vlax-curve-getEndParam obj)
          anginc (* pi (/ 7.5 180.0)))
    (setq tparam param)
      (while (<= param endparam)
        (setq pt (vlax-curve-getPointAtParam obj param))
        (if (not (equal pt (car ptlst) 1e-12))
          (setq ptlst (cons pt ptlst)))
        (if  (and (/= param endparam)
            (setq blg (abs (vlax-invoke obj 'GetBulge param)))
            (/= 0 blg))
          (progn
            (setq delta (* 4 (atan blg)) ;included angle
                  inc (/ 1.0 (1+ (fix (/ delta anginc))))
                  arcparam (+ param inc))
            (while (< arcparam (1+ param))
              (setq pt (vlax-curve-getPointAtParam obj arcparam)
                    ptlst (cons pt ptlst)
                    arcparam (+ inc arcparam))))
        )
        (setq param (1+ param)))
    (if (and (apply 'and ptlst)
        (> (length ptlst) 1))
     (ZClosed (reverse ptlst)))) ;end
  (defun TraceACE (obj / startparam endparam anginc
                         delta div inc pt ptlst)
    (setq startparam (vlax-curve-getStartParam obj)
          endparam (vlax-curve-getEndParam obj)
          anginc (* pi (/ 5.0 180.0)))
    (if (equal endparam (* pi 2) 1e-12)
      (setq delta endparam)
      (setq delta (NormalAngle (- endparam startparam))))
    (setq div (1+ (fix (/ delta anginc)))
          inc (/ delta div))
    (while (or
        (< startparam endparam)
        (equal startparam endparam 1e-12))
      (setq pt (vlax-curve-getPointAtParam obj startparam)
            ptlst (cons pt ptlst)
            startparam (+ inc startparam)))
    (reverse ptlst)) ;end
  (defun TraceLine (obj)(list (vlax-get obj 'StartPoint)
        (vlax-get obj 'EndPoint)))
  (defun TraceSpline (obj / startparam endparam ncpts inc param
                            fd ptlst pt1 pt2 ang1 ang2 a)
    (setq startparam (vlax-curve-getStartParam obj)
          endparam (vlax-curve-getEndParam obj)
          ncpts (vlax-get obj 'NumberOfControlPoints)
          inc (/ (- endparam startparam) (* ncpts 7))
          param (+ inc startparam)
          fd (vlax-curve-getfirstderiv obj param)
          ptlst (cons (vlax-curve-getStartPoint obj) ptlst))
    (while (< param endparam)
      (setq pt1 (vlax-curve-getPointAtParam obj param)
            ang1 fd
            param (+ param inc)
            pt2 (vlax-curve-getPointAtParam obj param)
            fd (vlax-curve-getfirstderiv obj param)
            ang2 fd
            a (abs (3d_angw1w2 ang1 ang2)))
      (if (> a 0.00218166)(setq ptlst (cons pt1 ptlst))))
    (if (not (equal
          (setq pt1 (vlax-curve-getEndPoint obj)) (car ptlst) 1e-8))
      (setq ptlst (cons pt1 ptlst)))
    (reverse ptlst)) ;end
  (defun TraceType1Pline (obj / ptlst objlst lst)
    (setq ptlst (list (vlax-curve-getStartPoint obj))
          objlst (vlax-invoke obj 'Explode))
    (foreach x objlst
      (setq lst (TraceACE x))
      (if (not (equal (car lst) (last ptlst) 1e-8))
        (setq lst (reverse lst)))
      (setq ptlst (append ptlst (cdr lst)))
      (vla-delete x))(ZClosed  ptlst)) ;end
  (defun TraceType23Pline (obj / objlst ptlst lastpt)
    (setq objlst (vlax-invoke obj 'Explode)
          lastpt (vlax-get (last objlst) 'EndPoint))
    (foreach x objlst
      (setq ptlst (cons (vlax-get x 'StartPoint) ptlst))
      (vla-delete x))(ZClosed (reverse (cons lastpt ptlst)))) ;end
  (defun Trace3DPline (obj / coord ptlst)
    (setq coord (vlax-get obj 'Coordinates))
    (repeat (/ (length coord) 3)
      (setq ptlst (cons (list (car coord) (cadr coord)(caddr coord)) ptlst))
      (setq coord (cdddr coord)))(ZClosed (reverse ptlst))) ;end
(defun NormalAngle (a)(if (numberp a)(angtof (angtos a 0 14) 0)))
(defun 3d_angw1w2 (Wekt1 Wekt2 / CosA)
 (if (equal (setq CosA (/ (apply '+ (mapcar '* Wekt1 Wekt2))
        (distance '(0 0 0) Wekt1) (distance '(0 0 0) Wekt2))) -1.0 1e-6)
  Pi
  (if (equal CosA 0.0 1e-6) (* 0.5 PI)(atan (sqrt (- 1 (* CosA CosA))) CosA))))
  (setq typlst '("AcDb2dPolyline" "AcDbPolyline" "AcDb3dPolyline" "AcDbCircle"
     "AcDbArc" "AcDbEllipse" "AcDbSpline" "AcDbLine"))
  (or (eq (type obj) 'VLA-OBJECT)
    (setq obj (vlax-ename->vla-object obj)))
  (setq typ (vlax-get obj 'ObjectName))
  (if (vl-position typ typlst)
    (cond ((or (eq typ "AcDb2dPolyline") (eq typ "AcDbPolyline"))
      (cond ((or
               (not (vlax-property-available-p obj 'Type))
               (= 0 (vlax-get obj 'Type)))
              (TracePline obj))
            ((or (= 3 (vlax-get obj 'Type)) (= 2 (vlax-get obj 'Type)))
              (TraceType23Pline obj))
            ((= 1 (vlax-get obj 'Type))
              (TraceType1Pline obj))))
       ((eq typ "AcDbLine")(TraceLine obj))
       ((or (eq typ "AcDbCircle") (eq typ "AcDbArc") (eq typ "AcDbEllipse"))
         (TraceACE obj))
       ((eq typ "AcDbSpline")(TraceSpline obj))
       ((eq typ "AcDb3dPolyline")(Trace3DPline obj))
    )))
(vl-load-com)
  (setq en (car(entsel "\nУкажите контур: ")))
  (if (and en (wcmatch (cdr(assoc 0 (entget en))) "*POLYLINE,SPLINE,CIRCLE,ARC,ELLIPSE"))
    (progn
      (setq lst (TraceObject (vlax-ename->vla-object en)))
      (lib:Zoom2Lst lst);_Гарантированно полилиния на экране
      (setq lst (mapcar '(lambda(x)(trans x 0 1)) lst))
      (setq lst (mapcar '(lambda(x)(list (car x)(cadr x))) lst))
(if (setq ss (ssget opt lst))(SSSETFIRST ss ss))
(setq ss nil)))(princ))
;_Select Contour Window Polygon
(defun C:SCWP ()(SelectContour "_WP"))
;_Select Contour Crossing Polygon
(defun C:SCCP ()(SelectContour "_CP"))
(princ "\nНаберите в командной строке SCWP или SCCP")

Re: LISP.Выделение объектов в области контура

Владимир Азарко,
Спасибо ОГРОМНОЕ!!!!!!!!! :D  :D  :D
Все работает отлично!!! :idea:

Re: LISP.Выделение объектов в области контура

Вопрос к гуру: а можно переделать lisp так, чтобы выделить все, а макрос сам определил какие объекты являются вложенными и удалил их, оставив на чертеже только внешние контура (их может быть много).
и в продолжение (усложнение :D ) сделать так, чтобы в качестве контура можно было использовать не замкнутые полилинии, а набор каких-то объектов (например, тех же самых полининий).

За ранее спасибо...

Re: LISP.Выделение объектов в области контура

VVA пишет:

    anginc (* pi (/ 7.5 180.0)))

Не очень понял почему расчет дуги поллинии производиться с таким упрощением. По итогу дуга условно делиться на (угол дуги/7,5), соответственно дуга с углом 20 градусов будет заменена 3 гранями. В результате объекты находящиеся близко к дуге могут быть не выделены.

P.S. Спасибо за лисп, почерпнул интересные решения.