Re: LISP. Построение перпендикуляров к любым линейным примитивам

Да я попробывал в 2007-м и ошибка иногда возникает и очень странная. При установке UCS по трём точкам Автокад сообщает что точки либо совпадают либо находятся на одной прямой. Проконтролировал в режиме отладки (дополнительно даже окружности строил) ничего подобного точки разные. Увеличил расчётное расстояние в (polar - никакого эффекта. В общем я пока не понимаю в чём причина такого поведения. Сегодня и завтра времени не будет, а после завтра постараюсь разобраться подробнее и локализовать проблему.

Re: LISP. Построение перпендикуляров к любым линейным примитивам

Бошьшое спасибо, можете специально не торопиться )

Re: LISP. Построение перпендикуляров к любым линейным примитивам

Возможно, исправить ошибку в программе?

Re: LISP. Построение перпендикуляров к любым линейным примитивам

Вроде работает, попробуйте. Пришлось экстремально увеличить расчетное расстояние до точек по которым создается UCS до 100000 иначе при маленьком зуме команда UCS воспринимала эти точки как совпадающие или лежащие на одной прямой. Если не будет работать сообщите. Придётся написать функцию связывающую текущий зум и требуемые расстояния.

(defun c:per(/ oldEcho oldOsm uPnt sSet oldOrt
        sCurve Dr Ang1 Ang2 pt1 pt2 *error*
       actDoc actLay actSp oldSt xl1 xl2)
  (vl-load-com)
  (defun *error* (msg)
    (setvar "ORTHOMODE" oldOrt)
    (command "_.ucs" "_p")
    (command "_.ucs" "_p")
    (setvar "CMDECHO" oldEcho)
    (setvar "OSMODE" oldOsm)
    (if(and xl1 xl2)
      (progn
      (vla-put-Lock actLay :vlax-false)
      (vla-delete xl1)(vla-delete xl2)
      (vla-put-Lock actLay oldSt)
      ); end progn
      ); end if
    (vla-EndUndoMark actDoc)
    (princ)
    ); end of *error*
  (setq oldEcho(getvar "CMDECHO")
        oldOsm(getvar "OSMODE")
        oldOrt(getvar "ORTHOMODE")
   ); end setq
  (setvar "CMDECHO" 0)
  (setvar "OSMODE" 819)
  (command "_.ucs" "_w")
  (setq actDoc(vla-get-ActiveDocument
        (vlax-get-acad-object))
  actLay(vla-get-ActiveLayer actDoc)
  oldSt(vla-get-Lock actLay)
  ); end setq
(vla-StartUndoMark actDoc)
  (if
    (and
    (setq uPnt(getpoint "\nSelect point at line or curve -> "))
    (setq sSet(ssget uPnt '((0 . "*LINE,ARC,ELLIPSE,CIRCLE,RAY,XLINE")
               (-4 . "<NOT")(0 . "MLINE")(-4 . "NOT>"))))
    (setq sCurve(vlax-ename->vla-object(ssname sSet 0)))
    (setq Dr(vlax-curve-getFirstDeriv sCurve
      (vlax-curve-getParamAtPoint sCurve uPnt)))
     ); end and
    (progn
      (if(=(cadr dr) 0.0)
  (setq Ang1 0.0)
  (setq Ang1(- pi(atan(/(car dr)(cadr dr)))))
  ); end if
      (setq Ang2(- Ang1(/ pi 2))
            pt1 (polar uPnt Ang1 100000.0)
            pt2 (polar uPnt Ang2 100000.0)
      ); end setq
      (if(= 1(vla-get-ActiveSpace actDoc))
  (setq actSp(vla-get-ModelSpace actDoc))
  (setq actSp(vla-get-PaperSpace actDoc))
  ); end if
      (vla-put-Lock actLay :vlax-false)
      (setq xl1(vla-AddXline actSp
                 (vlax-3D-point uPnt)
                   (vlax-3D-point pt1))
      xl2(vla-AddXline actSp
           (vlax-3D-point uPnt)
            (vlax-3D-point pt2))
      ); end setq
      (vla-put-color xl1 130)
      (vla-put-color xl2 51)
      (vla-Highlight xl1 :vlax-true)
      (vla-Highlight xl2 :vlax-true)
      (command "_.ucs" "_3" uPnt pt1 pt2)
      (setvar "ORTHOMODE" 1)
      (princ "\nSpecify length: ")
      (setvar "OSMODE" 2080)
      (command "_.line" (trans uPnt 0 1) pause "")
      (vla-delete xl1)(vla-delete xl2)
      (vla-put-Lock actLay oldSt)
      (command "_.ucs" "_p")
      (command "_.ucs" "_p")
      (setvar "ORTHOMODE" oldOrt)
      ); end progn
    ); end if
  (setvar "CMDECHO" oldEcho)
  (setvar "OSMODE" oldOsm)
  (vla-EndUndoMark actDoc)
  (princ)
  ); end of c:per

Re: LISP. Построение перпендикуляров к любым линейным примитивам

> {Smirnoff}
А может перед UCS по 3 точкам установить OSMODE в 0? Не поможет?

Re: LISP. Построение перпендикуляров к любым линейным примитивам

> Александр Ривилис
Спасибо вроде работает, но надо пробывать, потому что у меня эта ошибка иногда проявляется, а иногода нет. Но на этот раз интуитивно чувствую что причина в этом. Не думал что OSMODE влияет не только на отрисовку, но и на такие вещи. Как не странно в версиях 2002-2005 и так все нормально работало.

(defun c:per(/ oldEcho oldOsm uPnt sSet oldOrt
        sCurve Dr Ang1 Ang2 pt1 pt2 *error*
       actDoc actLay actSp oldSt xl1 xl2)
  (vl-load-com)
  (defun *error* (msg)
    (setvar "ORTHOMODE" oldOrt)
    (command "_.ucs" "_p")
    (command "_.ucs" "_p")
    (setvar "CMDECHO" oldEcho)
    (setvar "OSMODE" oldOsm)
    (if(and xl1 xl2)
      (progn
      (vla-put-Lock actLay :vlax-false)
      (vla-delete xl1)(vla-delete xl2)
      (vla-put-Lock actLay oldSt)
      ); end progn
      ); end if
    (vla-EndUndoMark actDoc)
    (princ)
    ); end of *error*
  (setq oldEcho(getvar "CMDECHO")
        oldOsm(getvar "OSMODE")
        oldOrt(getvar "ORTHOMODE")
   ); end setq
  (setvar "CMDECHO" 0)
  (setvar "OSMODE" 819)
  (command "_.ucs" "_w")
  (setq actDoc(vla-get-ActiveDocument
        (vlax-get-acad-object))
  actLay(vla-get-ActiveLayer actDoc)
  oldSt(vla-get-Lock actLay)
  ); end setq
(vla-StartUndoMark actDoc)
  (if
    (and
    (setq uPnt(getpoint "\nSelect point at line or curve -> "))
    (setq sSet(ssget uPnt '((0 . "*LINE,ARC,ELLIPSE,CIRCLE,RAY,XLINE")
               (-4 . "<NOT")(0 . "MLINE")(-4 . "NOT>"))))
    (setq sCurve(vlax-ename->vla-object(ssname sSet 0)))
    (setq Dr(vlax-curve-getFirstDeriv sCurve
      (vlax-curve-getParamAtPoint sCurve uPnt)))
     ); end and
    (progn
      (if(=(cadr dr) 0.0)
  (setq Ang1 0.0)
  (setq Ang1(- pi(atan(/(car dr)(cadr dr)))))
  ); end if
      (setq Ang2(- Ang1(/ pi 2))
            pt1 (polar uPnt Ang1 1.0)
            pt2 (polar uPnt Ang2 1.0)
      ); end setq
      (if(= 1(vla-get-ActiveSpace actDoc))
  (setq actSp(vla-get-ModelSpace actDoc))
  (setq actSp(vla-get-PaperSpace actDoc))
  ); end if
      (vla-put-Lock actLay :vlax-false)
      (setq xl1(vla-AddXline actSp
                 (vlax-3D-point uPnt)
                   (vlax-3D-point pt1))
      xl2(vla-AddXline actSp
           (vlax-3D-point uPnt)
            (vlax-3D-point pt2))
      ); end setq
      (vla-put-color xl1 130)
      (vla-put-color xl2 51)
      (vla-Highlight xl1 :vlax-true)
      (vla-Highlight xl2 :vlax-true)
      (setvar "OSMODE" 0)
      (command "_.ucs" "_3" uPnt pt1 pt2)
      (setvar "OSMODE" oldOsm)
      (setvar "ORTHOMODE" 1)
      (princ "\nSpecify length: ")
      (setvar "OSMODE" 2080)
      (command "_.line" (trans uPnt 0 1) pause "")
      (vla-delete xl1)(vla-delete xl2)
      (vla-put-Lock actLay oldSt)
      (command "_.ucs" "_p")
      (command "_.ucs" "_p")
      (setvar "ORTHOMODE" oldOrt)
      ); end progn
    ); end if
  (setvar "CMDECHO" oldEcho)
  (setvar "OSMODE" oldOsm)
  (vla-EndUndoMark actDoc)
  (princ)
  ); end of c:per

Re: LISP. Построение перпендикуляров к любым линейным примитивам

> {Smirnoff}
OSMODE влияет на любую команду, которая запрашивает точки. Почему небыло сбоя в предыдущих версиях AutoCAD - не знаю. Должен был быть. Поэтому необходимо или устанавливать OSMODE в 0 или (что может быть удобнее) перед вводом точек ставить "_none". Например, вместо:

(command "_.ucs" "_3" uPnt pt1 pt2)

может быть:

(command "_.ucs" "_3" "_none" uPnt "_none" pt1 "_none" pt2)

Длинне, но нет необходимости отслеживать значение OSMODE.

Re: LISP. Построение перпендикуляров к любым линейным примитивам

После отмены команды по ESC выводится ошибка
Список последних использовавшихся систем координат пуст.
; ошибка: В функции *error* возникла ошибка:Функция отменена

Re: LISP. Построение перпендикуляров к любым линейным примитивам

> Александр Ривилис
Спасибо за разяснения.

> gest
Действительно если сразу нажать Esc есть грешок.
Устанил.

(defun c:per(/ oldEcho oldOsm uPnt sSet oldOrt
        sCurve Dr Ang1 Ang2 pt1 pt2 *error*
       actDoc actLay actSp oldSt xl1 xl2)
  (vl-load-com)
  (defun *error* (msg)
    (if oldOrt
      (progn
        (setvar "ORTHOMODE" oldOrt)
        (setvar "CMDECHO" oldEcho)
        (setvar "OSMODE" oldOsm)
        (vla-EndUndoMark actDoc)
    ); end progn
      ); end if
    (if(and xl1 xl2)
      (progn
      (vla-put-Lock actLay :vlax-false)
      (vla-delete xl1)(vla-delete xl2)
      (command "_.ucs" "_p")
      (command "_.ucs" "_p")
      (vla-put-Lock actLay oldSt)
      ); end progn
      ); end if
    (princ)
    ); end of *error*
  (setq oldEcho(getvar "CMDECHO")
        oldOsm(getvar "OSMODE")
        oldOrt(getvar "ORTHOMODE")
   ); end setq
  (setvar "CMDECHO" 0)
  (setvar "OSMODE" 819)
  (command "_.ucs" "_w")
  (setq actDoc(vla-get-ActiveDocument
        (vlax-get-acad-object))
  actLay(vla-get-ActiveLayer actDoc)
  oldSt(vla-get-Lock actLay)
  ); end setq
(vla-StartUndoMark actDoc)
  (if
    (and
    (setq uPnt(getpoint "\nSelect point at line or curve -> "))
    (setq sSet(ssget uPnt '((0 . "*LINE,ARC,ELLIPSE,CIRCLE,RAY,XLINE")
               (-4 . "<NOT")(0 . "MLINE")(-4 . "NOT>"))))
    (setq sCurve(vlax-ename->vla-object(ssname sSet 0)))
    (setq Dr(vlax-curve-getFirstDeriv sCurve
      (vlax-curve-getParamAtPoint sCurve uPnt)))
     ); end and
    (progn
      (if(=(cadr dr) 0.0)
  (setq Ang1 0.0)
  (setq Ang1(- pi(atan(/(car dr)(cadr dr)))))
  ); end if
      (setq Ang2(- Ang1(/ pi 2))
            pt1 (polar uPnt Ang1 100000.0)
            pt2 (polar uPnt Ang2 100000.0)
      ); end setq
      (if(= 1(vla-get-ActiveSpace actDoc))
  (setq actSp(vla-get-ModelSpace actDoc))
  (setq actSp(vla-get-PaperSpace actDoc))
  ); end if
      (vla-put-Lock actLay :vlax-false)
      (setq xl1(vla-AddXline actSp
                 (vlax-3D-point uPnt)
                   (vlax-3D-point pt1))
      xl2(vla-AddXline actSp
           (vlax-3D-point uPnt)
            (vlax-3D-point pt2))
      ); end setq
      (vla-put-color xl1 130)
      (vla-put-color xl2 51)
      (vla-Highlight xl1 :vlax-true)
      (vla-Highlight xl2 :vlax-true)
      (command "_.ucs" "_3" uPnt pt1 pt2)
      (setvar "ORTHOMODE" 1)
      (princ "\nSpecify length: ")
      (setvar "OSMODE" 2080)
      (command "_.line" (trans uPnt 0 1) pause "")
      (vla-delete xl1)(vla-delete xl2)
      (vla-put-Lock actLay oldSt)
      (command "_.ucs" "_p")
      (command "_.ucs" "_p")
      (setvar "ORTHOMODE" oldOrt)
      ); end progn
    ); end if
  (setvar "CMDECHO" oldEcho)
  (setvar "OSMODE" oldOsm)
  (vla-EndUndoMark actDoc)
  (princ)
  ); end of c:per

Re: LISP. Построение перпендикуляров к любым линейным примитивам

> [Re:] pavel
А где ф-я (STORE) ?