AbdRF Posted April 8, 2020 Posted April 8, 2020 Hello, I have tried to write a simple lisp to change the rotation of the crosshair angle as that of line selected by user and also to switch it back to its orientation.Here is my trial- (defun c:Rchon (/ a b pntl pnt2 angl) (setq a (entsel "Select line: ")) (setq b (entget (car a))) (setq pntl (cdr (assoc 10 b))) (setq pnt2 (cdr (assoc 11 b))) (setq angl (angle pntl pnt2)) (setvar "snapang" ang1) (princ) ) (defun c:Rchoff () (setvar "snapang" 0) (princ) ) (princ) But I am getting following error- Quote Select line: ; error: AutoCAD variable setting rejected: "snapang" nil How to resolve this error? Thanks Quote
rkmcswain Posted April 8, 2020 Posted April 8, 2020 (setq angl (angle pntl pnt2)) (setvar "snapang" ang1) The variables are not the same: (converted to uppercase) ANGL ANG1 Quote
Jonathan Handojo Posted April 8, 2020 Posted April 8, 2020 1 hour ago, AbdRF said: Hello, I have tried to write a simple lisp to change the rotation of the crosshair angle as that of line selected by user and also to switch it back to its orientation.Here is my trial- (defun c:Rchon (/ a b pntl pnt2 angl) (setq a (entsel "Select line: ")) (setq b (entget (car a))) (setq pntl (cdr (assoc 10 b))) (setq pnt2 (cdr (assoc 11 b))) (setq angl (angle pntl pnt2)) (setvar "snapang" ang1) (princ) ) (defun c:Rchoff () (setvar "snapang" 0) (princ) ) (princ) But I am getting following error- How to resolve this error? Thanks Yes, it's exactly as rkmcswain said. That should fix the issue by doing (setvar "snapang" angl) Quote
dlanorh Posted April 8, 2020 Posted April 8, 2020 Although for a line you could just (defun c:Rchon (/ a ) (setq a (car (entsel "Select line: "))) (setvar 'snapang (angle '(0.0 0.0 0.0) (vlax-curve-getfirstderiv a 0))) (princ) ) Quote
BIGAL Posted April 9, 2020 Posted April 9, 2020 Will set angle to 1st segment of a multi segment pline. Could add the pline any segment should be able to use one of the vlax-curve functions the 1stderiv, need to have a think. Also 1 defun if ang is 0 do defun else reset to 0 Quote
AbdRF Posted April 9, 2020 Author Posted April 9, 2020 (edited) 14 hours ago, Jonathan Handojo said: Yes, it's exactly as rkmcswain said. That should fix the issue by doing (setvar "snapang" angl) Yup guys @Jonathan Handojo @rkmcswain that was so silly mistake on my part. Now it is working Edited April 9, 2020 by AbdRF Quote
AbdRF Posted April 9, 2020 Author Posted April 9, 2020 14 hours ago, dlanorh said: Although for a line you could just (defun c:Rchon (/ a ) (setq a (car (entsel "Select line: "))) (setvar 'snapang (angle '(0.0 0.0 0.0) (vlax-curve-getfirstderiv a 0))) (princ) ) @dlanorh thanks for your input.To be frank,I am quite a beginner in lisp and have not much knowledge of vlax function.But I will try it out Quote
dlanorh Posted April 9, 2020 Posted April 9, 2020 6 hours ago, BIGAL said: Will set angle to 1st segment of a multi segment pline. Could add the pline any segment should be able to use one of the vlax-curve functions the 1stderiv, need to have a think. Also 1 defun if ang is 0 do defun else reset to 0 (defun c:Rchon (/ sel ent pt ) (setq sel (entsel "Select Line/Arc/Polyline : ")) (cond (sel (setq ent (car sel) pt (vlax-curve-getclosestpointto ent (cadr sel)) ) (setvar 'snapang (angle '(0.0 0.0 0.0) (vlax-curve-getfirstderiv ent (vlax-curve-getparamatpoint ent pt)))) ) (t (setvar 'snapang 0.0)) );end_cond (princ) ) Will set the snapang to the angle at the closest point of the picked object (Arc, Circle, Ellipse, Line, Polyline, Ray, Spline, Xline). Won't work with Mlines. Select an empty part of the screen to reset. 1 Quote
AbdRF Posted April 9, 2020 Author Posted April 9, 2020 3 hours ago, dlanorh said: (defun c:Rchon (/ sel ent pt ) (setq sel (entsel "Select Line/Arc/Polyline : ")) (cond (sel (setq ent (car sel) pt (vlax-curve-getclosestpointto ent (cadr sel)) ) (setvar 'snapang (angle '(0.0 0.0 0.0) (vlax-curve-getfirstderiv ent (vlax-curve-getparamatpoint ent pt)))) ) (t (setvar 'snapang 0.0)) );end_cond (princ) ) Will set the snapang to the angle at the closest point of the picked object (Arc, Circle, Ellipse, Line, Polyline, Ray, Spline, Xline). Won't work with Mlines. Select an empty part of the screen to reset. Awesome stuff @dlanorh Quote
Lee Mac Posted April 9, 2020 Posted April 9, 2020 Here's another existing option to consider. 1 1 Quote
AbdRF Posted April 9, 2020 Author Posted April 9, 2020 11 minutes ago, Lee Mac said: Here's another existing option to consider. @Lee Mac your lisp are cool as usual.Good one ! Quote
Jonathan Handojo Posted April 9, 2020 Posted April 9, 2020 2 hours ago, Lee Mac said: Here's another existing option to consider. So I was analysing that code, and got confused: How is this not yielding an error? (and (setq e (car l) o (vlax-ename->vla-object e) ) (vlax-property-available-p o 'rotation) (setq a (vla-get-rotation o)) ) I was logically thinking, if o doesn't have the rotation property, shouldn't a be an error? Because similarly speaking on the topic, I used snapang on my LISP code below to align all insertion points and texts to a specific direction while also using grread to visualise your outputs easier (though it tends to be slow after running it multiple times.) (defun JH:selset-to-list-vla (ss / rtn) (if ss (repeat (setq i (sslength ss)) (setq rtn (cons (vlax-ename->vla-object (ssname ss (setq i (1- i)))) rtn)) ) ) (reverse rtn) ) (defun c:adjustangle ( / *error* acadobj activeundo adoc alpts ang angs halfpi movdis msp opts p1 p2 p3 snp ss) (defun *error* ( msg ) (setvar 'snapang snp) (vla-EndUndoMark adoc) (if (not (wcmatch (strcase msg T) "*break*,*cancel*,*exit*")) (princ (strcat "Error: " msg)) ) ) (setq acadobj (vlax-get-acad-object) adoc (vla-get-ActiveDocument acadobj) msp (vla-get-ModelSpace adoc) activeundo nil) (if (= 0 (logand 8 (getvar "UNDOCTL"))) (vla-StartUndoMark adoc) (setq activeundo T)) (setq snp (getvar 'snapang)) (setq angs '( (0 . "degrees") (1 . "degrees, minutes, and seconds") (2 . "grads") (3 . "radians") (4 . "surveyor units") ) ) (if (setq ss (vl-remove-if-not '(lambda (x) (or (vlax-property-available-p x 'insertionpoint) (vlax-property-available-p x 'textposition) (vlax-property-available-p x 'textalignmentpoint) ) ) (JH:selset-to-list-vla (ssget "_:L")) ) ) (progn (setq opts (progn (initget 1 "X Y Angle") (getkword "\nSpecify alignment direction [X/Y/Angle]: ")) ang (+ (setq halfpi (* 0.5 pi)) (cond ((eq opts "X") 0) ((eq opts "Y") halfpi) ((getangle (strcat "\nSpecify angle in " (cdr (assoc (getvar "AUNITS") angs)) " or click two points to determine direction: "))) ) ) p1 (last (grread T 15 0)) p2 (polar p1 ang 1) alpts (mapcar '(lambda (x / p3) (list x (inters p1 p2 (setq p3 (vlax-get x (cond ((vlax-property-available-p x 'insertionpoint) (if (vlax-property-available-p x 'textalignmentpoint) (if (null (equal (vlax-get x 'textalignmentpoint) '(0 0 0) 1e-8)) 'textalignmentpoint 'insertionpoint) 'insertionpoint ) ) ((vlax-property-available-p x 'textalignmentpoint) 'textalignmentpoint) ((vlax-property-available-p x 'textposition) 'textposition) ((vlax-property-available-p x 'insertionpoint) 'insertionpoint) ) ) ) (polar p3 (+ halfpi ang) 1) nil ) ) ) ss ) ) (setvar 'snapang ang) (while (progn (setq gr (grread T 15 0) grp (last gr) grv (car gr) ) (cond ((= grv 5) (setq movdis (distance p1 (inters grp (polar grp ang 1) p1 (polar p1 (- ang halfpi) 1) nil) ) ) (foreach x alpts (vlax-put (car x) (cond ((vlax-property-available-p (car x) 'insertionpoint) (if (vlax-property-available-p (car x) 'textalignmentpoint) (if (null (equal (vlax-get (car x) 'textalignmentpoint) '(0 0 0) 1e-8)) 'textalignmentpoint 'insertionpoint) 'insertionpoint ) ) ((vlax-property-available-p (car x) 'textalignmentpoint) 'textalignmentpoint) ((vlax-property-available-p (car x) 'textposition) 'textposition) ((vlax-property-available-p (car x) 'insertionpoint) 'insertionpoint) ) (polar (last x) ((lambda (y) (if (LM:Clockwise-p p1 (polar p1 ang 1) grp) y (+ y pi) ) ) (- ang halfpi) ) movdis ) ) ) T ) ((or (and (= grv 2) (vl-position grp '(13 32))) (= grv 3)) nil) (T) ) ) ) ) ) (setvar 'snapang snp) (if activeundo nil (vla-EndUndoMark adoc)) (princ) ) ;; Clockwise-p - Lee Mac ;; Returns T if p1,p2,p3 are clockwise oriented (defun LM:Clockwise-p ( p1 p2 p3 ) ((lambda ( n ) (< (car (trans p2 0 n)) (car (trans p1 0 n)))) (mapcar '- p1 p3)) ) I had to do it this way: (if (vlax-property-available-p x 'textalignmentpoint) (if (null (equal (vlax-get x 'textalignmentpoint) '(0 0 0) 1e-8)) 'textalignmentpoint 'insertionpoint) 'insertionpoint ) Quote
dlanorh Posted April 9, 2020 Posted April 9, 2020 1 hour ago, Jonathan Handojo said: So I was analysing that code, and got confused: How is this not yielding an error? (and (setq e (car l) o (vlax-ename->vla-object e) ) (vlax-property-available-p o 'rotation) (setq a (vla-get-rotation o)) ) I was logically thinking, if o doesn't have the rotation property, shouldn't a be an error? You should notice that they are wrapped in an "and" statement. If o doesn't have a rotation property it will return false and the "and" will fail before getting to the (setq a ..) Quote
Lee Mac Posted April 9, 2020 Posted April 9, 2020 4 hours ago, AbdRF said: @Lee Mac your lisp are cool as usual.Good one ! Thank you! 2 hours ago, Jonathan Handojo said: So I was analysing that code, and got confused: How is this not yielding an error? (and (setq e (car l) o (vlax-ename->vla-object e) ) (vlax-property-available-p o 'rotation) (setq a (vla-get-rotation o)) ) I was logically thinking, if o doesn't have the rotation property, shouldn't a be an error? This exploits a feature of LISP known as short-circuit evaluation, whereby arguments of a boolean operator are successively evaluated until the boolean operator has an unambiguous return. In this particular example, arguments are evaluated until an argument returns nil, at which point the and expression cannot possibly return T and so no further arguments need to be evaluated. It is worth noting that short-circuit evaluation is not a standard feature of all programming languages, for example, the equivalent expression in VBA would indeed raise an exception, as VBA does not support short-circuit evaluation. 55 minutes ago, dlanorh said: You should notice that they are wrapped in an "and" statement. If o doesn't have a rotation property it will return false and the "and" will fail before getting to the (setq a ..) Exactly Quote
Jonathan Handojo Posted April 9, 2020 Posted April 9, 2020 (edited) 6 hours ago, Lee Mac said: 1 hour ago, Lee Mac said: Thank you! This exploits a feature of LISP known as short-circuit evaluation, whereby arguments of a boolean operator are successively evaluated until the boolean operator has an unambiguous return. In this particular example, arguments are evaluated until an argument returns nil, at which point the and expression cannot possibly return T and so no further arguments need to be evaluated. It is worth noting that short-circuit evaluation is not a standard feature of all programming languages, for example, the equivalent expression in VBA would indeed raise an exception, as VBA does not support short-circuit evaluation. Exactly That's a neat feature to know for AutoLISP. This will certainly shorten my codes some. Thanks. I suppose it's the same with the or function as soon as the first returns anything other than nil. In some ways it's so similar to vl-some Edited April 9, 2020 by Jonathan Handojo Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.