Cezar Barbalho Posted August 11, 2016 Posted August 11, 2016 Hi, i am no autolisper, and i am having trouble to adapt this excellent lisp made by Tharwat to my use... My problem is with the attributes upon insertion, after the command, no attribute appear on the drawing. I will not post my attempts on doing so, (for they are really messy...) but the original code and the description of what i inttend to do. My block has 3 attribs, ID, KM and M. ID must be prompted by user upon inserction; KM must be taken from the lwspline length (variable l), i.e.: if swpline is 350120,00 m long, then KM is 350, if swpline is 120,00m long, then KM is 000; M must be treated the same way as KM, but in 350120,00, M is 120 and so on... The text output format on the drawing is "km 350+120" Test.lsp [ATTACH]58954[/ATTACH] Quote
Tharwat Posted August 11, 2016 Posted August 11, 2016 Hi Cezar, Can you please upload a sample drawing showing what you are after? Quote
Cezar Barbalho Posted August 11, 2016 Author Posted August 11, 2016 Hi Cezar, Can you please upload a sample drawing showing what you are after? Sure!! sample.dwg BLOCO SINALEIRO.dwg Quote
Tharwat Posted August 11, 2016 Posted August 11, 2016 I am lost with that drawing , just upload an example with BEFORE & AFTER which means old and final result and there is no need for all the other objects in the drawing at the mean time to allow me to get what you want to do. Quote
Cezar Barbalho Posted August 11, 2016 Author Posted August 11, 2016 I am lost with that drawing , just upload an example with BEFORE & AFTER which means old and final result and there is no need for all the other objects in the drawing at the mean time to allow me to get what you want to do. Sorry, i think the next one is adequate... SAMPLE 2.dwg Quote
Tharwat Posted August 11, 2016 Posted August 11, 2016 The program did not work because it is written for regular blocks and not for attributed blocks. But for the sample drawing you provided the length of the polyline is 100.8675 and what to do in this case? Sorry I did not get what you mean by the following sentence ? what is if polyline is in different lengths? KM must be taken from the lwspline length (variable l), i.e.: if swpline is 350120,00 m long, then KM is 350, if swpline is 120,00m long, then KM is 000; Quote
Cezar Barbalho Posted August 11, 2016 Author Posted August 11, 2016 I see... i always join the polylines in one, for i am a railroad engineer and the polyline represents an railroad aligntment. Usually the drawing is in meters, and is kilometers long, in order to do my job manually, i have to measure the inserction point and write it down, this is really a big time consumer since there are hundreds of objects to be placed along kilometers of railroad at irregular intervals... it would save time if the placement and placement information where put via lisp. In that sentence, i tried to explain in "Lisp terms" what i do manually, in railroad drawing i can't supress the leading zeroes, if an item is placed at 120 meters from the start of the railroad, the correct information is that this item is placed at "kilometer 000 plus 120 meters" (km 000+120). Other example location could be that an item is located at "kilometer 350 plus 012 meters" (km 350+012). Eventually different project phases require centimeters input as if after the comma as "km 350+012,50", but this is not an so common case on my job... Sorry if i don't seem to express myself clearly, i am not used to english conversations, only english technical reading... Thanks for being comprehensive. I dont' mind in working with a regular block... but can i automatize the text insertion in another way? Quote
Cezar Barbalho Posted August 11, 2016 Author Posted August 11, 2016 Oh... I'm sorry, maybe you was talking about an polyline METERS long... in such a case, i would do the job manually. By the other hand, if the drawing units are in km, meters or unitless i would change it accordingly to adapt to the lisp functionalities. Quote
Tharwat Posted August 11, 2016 Posted August 11, 2016 I guess you still did not answer my question. You said that when the length of the polyline is 350120,00 m long, then KM is 350, if polyline is 120,00m long, then KM is 000 s what to do with the other lengths of selected polylines? Have a look at the last uploaded drawing and measure the length of the polyline to get what I am indicating to. Quote
Cezar Barbalho Posted August 11, 2016 Author Posted August 11, 2016 In the example the polyline is 100 meters long (Legth 100,8675 on acad properties display), so i need to show something like "km 000+100", if the length was multiplied by one thousand resulting in 100 km ( if it was Length 100867,500 on acad properties display), it should show something like "km 100+867". Again, sorry if i am not being clear, it's my fault because i am not fluent in english. In other terms, what i want is that this block have a text with it's position in a text formated to look like "km XXX + YYY" automatically. Quote
Tharwat Posted August 11, 2016 Posted August 11, 2016 This is really exhausting Try it and let me know. (defun c:Test (/ *error* blk bk atts sp s e l d v km m lng) ;; Tharwat 11.Aug.2016 ;; (defun *error* (msg) (if atts (mapcar 'setvar '(ATTREQ ATTDIA) atts) ) (and msg (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*EXIT*")) (princ (strcat "\nError => " msg)) ) (princ) ) (setq blk "BLOCO SINALEIRO") ;; Block name (if (and (tblsearch "BLOCK" blk) (princ "\nSelect LWpolyline :") (setq s (ssget "_+.:S:E" '((0 . "LWPOLYLINE")))) (setq l (vlax-curve-getdistatpoint (setq e (ssname s 0)) (vlax-curve-getendpoint e) ) ) ) (progn (setq atts (mapcar 'getvar '(ATTREQ ATTDIA)) sp (vlax-get (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object)) ) 'Block ) km (if (= (setq lng (length (vl-string->list (rtos l 2 0)))) 3) "000" (strcat (nth (- lng 3) '("" "00" "0")) (substr (rtos l 2 0) 1 (- lng 3)) ) ) m (if (= lng 3) (substr (rtos l 2 2) 1 3) (substr (rtos l 2 2) (1+ (- lng 3)) 3) ) ) (mapcar 'setvar '(ATTREQ ATTDIA) '(1 0)) (while (and (setq d (getdist (strcat "\nSpecify distance less than " (rtos l 2 2) " > :" ) ) ) (< d l) (/= "" (setq v (getstring t "\nSpecify Attribute Value :"))) (setq bk (vla-insertblock sp (vlax-3d-point (vlax-curve-getpointatdist e d)) blk 1.0 1.0 1.0 (+ (* pi 0.5) (angle '(0. 0. 0.) (vlax-curve-getfirstderiv e (vlax-curve-getparamatpoint e (vlax-curve-getpointatdist e d) ) ) ) ) ) ) ) (mapcar '(lambda (a) (vla-put-textstring a (nth (vl-position (vla-get-tagstring a) '("ID" "KM" "M")) (list v km m) ) ) ) (vlax-invoke bk 'getattributes) ) ) ) ) (if (> d l) (alert "\nLong distance entered !") ) (*error* nil) (princ) )(vl-load-com) Quote
Cezar Barbalho Posted August 11, 2016 Author Posted August 11, 2016 Ipressive mr Tharwat! But i think when i was trying to explain myself, i mistook variable "l" for variable "d"... because variable "d" is the insert point in distance, thus is the source for the information "km XXX+YYY"... I am trying to correct this, but i am not having much luck... sorry, but what do you think? Quote
Cezar Barbalho Posted August 11, 2016 Author Posted August 11, 2016 I think that if i put the SETQ d on the start, it would work, then i pass onto the SETQ km, m and so on... can you tell me if i am on the right course? Thanks (PROGN (SETQ d (GETDIST (STRCAT "\nSpecify distance less than " (RTOS l 2 2) " > :") ) atts (MAPCAR 'GETVAR '(attreq attdia)) sp (VLAX-GET (VLA-GET-ACTIVELAYOUT (VLA-GET-ACTIVEDOCUMENT (VLAX-GET-ACAD-OBJECT)) ) 'block ) km (IF (= (SETQ lng (LENGTH (VL-STRING->LIST (RTOS d 2 0)))) 3) "000" (IF (< lng 3 (STRCAT (NTH (- 3 lng) '("" "00" "0")) (SUBSTR (RTOS d 2 0) 1 (- lng 3)) ) ) ) ) m (IF (= lng 3) (SUBSTR (RTOS d 2 2) 1 3) (SUBSTR (RTOS d 2 2) (1+ (- lng 3)) 3) ) ) ) Quote
Tharwat Posted August 12, 2016 Posted August 12, 2016 Hi Cezar, It is okay, and don't worry I will modify the codes to suit your needs regardless of your mistake. So just explain your needs clearly compared to my final posted program in post# 11. Quote
Cezar Barbalho Posted August 12, 2016 Author Posted August 12, 2016 Hi Tharwat, compared to the previous version, I want to switch the variable "l" by the variable "d" on km (if (= (setq lng (length (vl-string->list (rtos l 2 0)))) 3) "000" (strcat (nth (- lng 3) '("" "00" "0")) (substr (rtos l 2 0) 1 (- lng 3)) ) ) m (if (= lng 3) (substr (rtos l 2 2) 1 3) (substr (rtos l 2 2) (1+ (- lng 3)) 3) ) I think that way, the attributes will show the information of the insertion point of the block. As it is now, it show me the total length of the polyline, not the location of the block relative to polyline length. In my attempt, I was trying to do this, first I put the SETQ "d" before the others, then I received error messages about the NTH function, so I was trying to understand it, I think I have learned much more in one day exchanging messages here than reading for one month. Am I on the right track? Quote
Tharwat Posted August 12, 2016 Posted August 12, 2016 Hi Cezar, The variable 'd' represents distance value which means real number ( decimal number ) and not block position. Show me an example with a drawing as you have did before to allow me to modify the program in one go. Quote
Cezar Barbalho Posted August 12, 2016 Author Posted August 12, 2016 Hi Tharwat, I hope this image can explain what i meant. Quote
Tharwat Posted August 12, 2016 Posted August 12, 2016 (edited) Hope this would work as expected, try it and let me know; (defun c:Test (/ *error* blk bk atts sp s e l d v km m lng) ;; Tharwat 11.Aug.2016 ;; (defun *error* (msg) (if atts (mapcar 'setvar '(ATTREQ ATTDIA) atts) ) (and msg (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*EXIT*")) (princ (strcat "\nError => " msg)) ) (princ) ) (setq blk "BLOCO SINALEIRO") ;; Block name (if (and (tblsearch "BLOCK" blk) (princ "\nSelect LWpolyline :") (setq s (ssget "_+.:S:E" '((0 . "LWPOLYLINE")))) (setq l (vlax-curve-getdistatpoint (setq e (ssname s 0)) (vlax-curve-getendpoint e) ) ) ) (progn (setq atts (mapcar 'getvar '(ATTREQ ATTDIA)) sp (vlax-get (vla-get-activelayout (vla-get-activedocument (vlax-get-acad-object)) ) 'Block ) ) (mapcar 'setvar '(ATTREQ ATTDIA) '(1 0)) (while (and (setq d (getdist (strcat "\nSpecify distance less than " (rtos l 2 2) " > :" ) ) ) (< d l) (/= "" (setq v (getstring t "\nSpecify Attribute Value :"))) (setq km (if (<= (setq lng (length (vl-string->list (rtos l 2 0)))) 3 ) "000" (strcat (nth (- lng 3) '("" "00" "0" "" "")) (substr (rtos l 2 0) 1 (- lng 3)) ) ) m (if (<= (setq lng (length (vl-string->list (rtos d 2 0)))) 3 ) (substr (rtos d 2 2) 1 3) (substr (rtos d 2 2) (1+ (- lng 3)) 3) ) bk (vla-insertblock sp (vlax-3d-point (vlax-curve-getpointatdist e d)) blk 1.0 1.0 1.0 (+ (* pi 0.5) (angle '(0. 0. 0.) (vlax-curve-getfirstderiv e (vlax-curve-getparamatpoint e (vlax-curve-getpointatdist e d) ) ) ) ) ) ) ) (mapcar '(lambda (a) (vla-put-textstring a (nth (vl-position (vla-get-tagstring a) '("ID" "KM" "M")) (list v km m) ) ) ) (vlax-invoke bk 'getattributes) ) ) ) ) (if (> d l) (alert "\nLong distance entered !") ) (*error* nil) (princ) )(vl-load-com) Edited August 14, 2016 by Tharwat Quote
Cezar Barbalho Posted August 12, 2016 Author Posted August 12, 2016 Hi Tharwat, it's working, but i have found a limitation on the polyline length, if i try to use a polyline longer than 100 kilometers, it freezes the program. This issue is something easy to work around? Quote
Tharwat Posted August 12, 2016 Posted August 12, 2016 Sorry, this is the third time you are talking about something different than what you have asked from your first post in this thread. I am confused about these different inputs and what you exactly want to do. I have spent too much time on this thread, and sorry I am not able to continue endlessly. 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.