Civils_Ben Posted October 31 Share Posted October 31 Hi all, first time poster here. Been searching around for a while on various sites for a Lisp routine that I can select an attribute block then apply the value in the block to a polyline's elevation. I even tried Chat GPT but this appears to be too complex for it so i thought I would ask the experts. CAD test file attached for assistance. test.dwg Apologies if this is in the wrong thread. Cheers, Ben Quote Link to comment Share on other sites More sharing options...
SLW210 Posted October 31 Share Posted October 31 I have moved your thread to the AutoLISP, Visual LISP & DCL Forum. Quote Link to comment Share on other sites More sharing options...
BIGAL Posted October 31 Share Posted October 31 Welcome aboard, there are 2 ways to set the elevations. You can also use nentsel to pick the attribute value directly from the block. (defun c:selev ( / ent ent2) (setq ent (car (nentsel "\nPick the attribute text "))) (setq elev (atof (cdr (assoc 1 (entget ent))))) (setq ent2 (entget (car (entsel "\nPick pline ")))) (entmod (subst (cons 38 elev) (assoc 38 ent2) ent2)) (princ) ) ; VL (defun c:selev ( / obj elev obj2) (setq obj (vlax-ename->vla-object (car (nentsel "\pick the attribute ")))) (setq elev (atof (vlax-get obj 'textstring))) (setq obj2 (vlax-ename->vla-object (car (entsel "\nPick the pline ")))) (vlax-put obj2 'elevation elev) (princ) ) Quote Link to comment Share on other sites More sharing options...
Tsuky Posted October 31 Share Posted October 31 With your dynamic bloc, try this... (defun c:att2elev ( / ss n ename dxf_ent dxf_10 ss_bl o l_att) (princ "\nSelect polyline") (setq ss (ssget (list (cons 0 "lWPOLYLINE") (cons 67 (if (eq (getvar "CVPORT") 1) 1 0)) (cons 410 (if (eq (getvar "CVPORT") 1) (getvar "CTAB") "Model")) (cons 8 "T_E_Construction layer") (cons -4 "&") (cons 70 1) ) ) ) (cond (ss (repeat (setq n (sslength ss)) (setq ename (ssname ss (setq n (1- n))) dxf_ent (entget ename) dxf_10 (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10))dxf_ent)) ss_bl (ssget "_WP" (mapcar '(lambda (x) (trans x 0 1)) dxf_10) '((0 . "INSERT") (2 . "`*U*") (8 . "T_E_FFL") (66 . 1))) ) (cond (ss_bl (if (= "T_E_FFL" (strcase (vla-get-effectivename (setq o (vlax-ename->vla-object (ssname ss_bl 0)))))) (progn (setq l_att (mapcar '(lambda (at) (list (Vla-get-tagstring at)(Vla-get-textstring at) at) ) (vlax-invoke o 'GetAttributes) ) ) (mapcar '(lambda (x) (if (eq (car x) "FFL") (entmod (subst (cons 38 (read (cadr x))) (assoc 38 dxf_ent) dxf_ent)) ) ) l_att ) ) ) ) ) ) ) ) (prin1) ) Quote Link to comment Share on other sites More sharing options...
marko_ribar Posted November 1 Share Posted November 1 Only one minor adjustment in @Tsuky code... This line : (setq ss_bl (ssget "_WP" (mapcar '(lambda (x) (trans x 0 1)) dxf_10) '((0 . "INSERT") (2 . "`*U*") (8 . "T_E_FFL") (66 . 1)))) Should be : (setq ss_bl (ssget "_WP" (mapcar '(lambda (x) (trans x ename 1)) dxf_10) '((0 . "INSERT") (2 . "`*U*") (8 . "T_E_FFL") (66 . 1)))) Quote Link to comment Share on other sites More sharing options...
Civils_Ben Posted November 6 Author Share Posted November 6 On 01/11/2024 at 14:36, marko_ribar said: Only one minor adjustment in @Tsuky code... This line : (setq ss_bl (ssget "_WP" (mapcar '(lambda (x) (trans x 0 1)) dxf_10) '((0 . "INSERT") (2 . "`*U*") (8 . "T_E_FFL") (66 . 1)))) Should be : (setq ss_bl (ssget "_WP" (mapcar '(lambda (x) (trans x ename 1)) dxf_10) '((0 . "INSERT") (2 . "`*U*") (8 . "T_E_FFL") (66 . 1)))) Thanks guys. However. Nothing happened with this code? Quote Link to comment Share on other sites More sharing options...
Civils_Ben Posted November 6 Author Share Posted November 6 On 31/10/2024 at 21:51, BIGAL said: Welcome aboard, there are 2 ways to set the elevations. You can also use nentsel to pick the attribute value directly from the block. (defun c:selev ( / ent ent2) (setq ent (car (nentsel "\nPick the attribute text "))) (setq elev (atof (cdr (assoc 1 (entget ent))))) (setq ent2 (entget (car (entsel "\nPick pline ")))) (entmod (subst (cons 38 elev) (assoc 38 ent2) ent2)) (princ) ) ; VL (defun c:selev ( / obj elev obj2) (setq obj (vlax-ename->vla-object (car (nentsel "\pick the attribute ")))) (setq elev (atof (vlax-get obj 'textstring))) (setq obj2 (vlax-ename->vla-object (car (entsel "\nPick the pline ")))) (vlax-put obj2 'elevation elev) (princ) ) Thanks for the reply. Nothing happened though. Quote Link to comment Share on other sites More sharing options...
BIGAL Posted November 6 Share Posted November 6 "Nothing happened though." Please explain more this statement does not tell us anything. Did you load the code and type say selev at command line ? Can add a while so it allows you to pick multiple objects. Quote Link to comment Share on other sites More sharing options...
Civils_Ben Posted November 7 Author Share Posted November 7 9 hours ago, BIGAL said: "Nothing happened though." Please explain more this statement does not tell us anything. Did you load the code and type say selev at command line ? Can add a while so it allows you to pick multiple objects. Apologies, I was rushing out the office last night. I realise that probably wasn't much help lol I've attached a video capture of Selev. I've created the Code and APPLOADed it. the att2elev I have done a video but its too large but essentially, created the code, APPLOADed it. It asks to select objects, which I do then nothing happens. Screenshot below. Thanks guys. Selev.mp4 Quote Link to comment Share on other sites More sharing options...
Tsuky Posted November 7 Share Posted November 7 @Civils_Ben If att2elev doesn't work, I think it's due to the name of the layer where the polylines are located. I fixed the name of the layer based on the drawing example you provided. Here is another version which will be more flexible (it will allow you to choose the layer(s), as well as the block attribute to take into consideration. att2elev.lsp Quote Link to comment Share on other sites More sharing options...
pkenewell Posted November 7 Share Posted November 7 @Civils_Ben Why not just use a FIELD? 1) Edit the Attribute using the Attribute editor. Right-click and select "Insert Field" 2) In the Field Dialog, Select "Objects" from the popdown list, then "Object" from the list below it: 3) In the middle of the top of the dialog, next to "Object type", use the button, then select the Polyline. 4) When the dialog returns, Select the "Elevation" Property, then set the units and precision on the right. 5) Select "OK" and then see the value displayed in the Attribute Editor. 6) Select OK, the the attribute will display the value. If you change the elevation, then use the UPDATEFIELD command on the block and the attribute will update. Quote Link to comment Share on other sites More sharing options...
BIGAL Posted November 7 Share Posted November 7 (edited) @pkenewell the attribute holds an elevation, the pline is at say 0.0, so need to set the pline elevation 1st, as you have suggested once the pline has an elevation you could using your method set the attribute to the pline elevation field, that way change the pline value and atrribute updates, matches current sample dwg. You could check the attribute string to see if a field if not then update pline & attribute. We need @Civils_Ben to confirm the choice of method, how is the elevation first worked out and do you set pline or attribute ? Is it auto labelled, Civil software can do that sort of thing. Just a comment , you could use a lisp as every time you insert the elevation block must get the ID of the corresponding pline. Edited November 7 by BIGAL 1 Quote Link to comment Share on other sites More sharing options...
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.