Silvercloak Posted June 28, 2018 Posted June 28, 2018 Hey all, Had a CAD user come to me complaining that some drawings this lisp (see blow) runs slow in some drawings and not others. So far, the only culprit I can see is the general segment labels. He's got about 900 of them in his drawing, and once I remove them - the lisp runs snappy. I can't figure out for the life of me what the correlation is between those labels and this lisp though. They seem completely un-related. When I set it to animate and watched it run, it hit it's biggest slog when it hits the "command" calls. Especially the layer ones. What that has to do with the general segment labels though - is beyond me. Anyone with any ideas? Here's the lisp; (defun C:a() (setq OLDLAY (getvar "CLAYER")) ;get current layer name (setq oldos(getvar "osmode")) ; get current osnap (command "layer" "set" "leg-area" "") ;Sets layer to leg-area (command "osnap" "none") ; clears osnap (command "style" "romans80I" "" "" "" "" "" "" "") ; sets style to Romans80I (defun ma() ;Defining function MA (setq b rmr); Gives the variable B a value of RMR (if (< rmr 1000) (setvar "luprec" 0)) (if (< rmr 100) (setvar "luprec" 1)) (if (< rmr 10) (setvar "luprec" 1)) (if (< rmr 1) (setvar "luprec" 1)) ) (defun ha() ;Defining the function of HA (setq b (/ rmr 10000)) ; Gives B The value of RMR divided by 10,000 (if (> b 100)(setvar "luprec" 0)) (if (< b 100)(setvar "luprec" 1)) (if (< b 10)(setvar "luprec" 2)) (if (< b 1)(setvar "luprec" 3)) ) (setq normal 0) ; Set variable normal to 0 (setq dcm (getstring "\nEnter [1] for strata or NULL for Legal :")) ; Set DCM Variable to user input (if (/= dcm "")(setq normal 1)) ; If nothing is entered DCM is set to 1 (command "area" "e" "\\"); Runs the command area - unsure of what the \\ is meant to do (setq rmr (getvar "area")) ;Sets the RMR variable to the recently selected area (if (> rmr 1000) (setq a " ha.")) ; If area is more than 1000 set variable a to HA (if (< rmr 1000) (setq a " m%%253")) ;if area is less than 1000 set variable a to M (if (= a " ha.") (ha) (ma)); If variable A equals HA then run HA else run MA (if (< rmr 1000) (setvar "luprec" 1)) ; If RMR is more than 1000 then set luprec variable to 1 (if (= normal 1)(setvar "luprec" 1)) ;If Normal is 1 then set luprec variable 1 (setq rmr (rtos b)) ; Set RMR to the value of B determined by the precision variable (setq rmr (strcat rmr a)) ; Set RMR value with either HA or MA as determined by the AREA variable (setvar "luprec" 3) ;Sets precision to 3 decimal places (SETQ DTXCENT (GETPOINT "Where ? ")); Determines where the text is placed (SETQ TEXTDEGANG "90D"); Sets text angle to 90 degrees (command "text" "c" dtxcent textdegang rmr);Prints the text on screen ;(command "osnap" "intersection,endpoint,node") (setvar "CLAYER" OLDLAY) ;reset active layer (setvar "osmode" OLDOS) ;reset active osnap (princ) ) Silvercloak Quote
hanhphuc Posted July 1, 2018 Posted July 1, 2018 (edited) Hey all,.... They seem completely un-related. When I set it to animate and watched it run, it hit it's biggest slog when it hits the "command" calls. Especially the layer ones. What that has to do with the general segment labels though - is beyond me. Anyone with any ideas? Here's the lisp; (defun C:a ( ) ...... Silvercloak hi your lisp is related to area, but what does segment mean? 1.localize variable 2.using cond or and instead of many if if if 3.entmake entity is faster 4.FWIW (setvar 'luprec [color="red"]2[/color]) ([color="blue"][b]rtos[/b][/color] number 2 [color="red"]2[/color]) (defun artos (x / u i) [color="green"]; Area Real To String - metric [/color] ;hanhphuc (eval (cons 'strcat (reverse (list (setq x (float x) u (if (< (setq i (/ (abs x) 1e+4)) 0.1) " m\U+00B2" " ha")) (cons '[color="blue"][b]rtos[/b][/color] (if (= u " ha") (list (/ x 1e+4) 2 ([color="blue"][b]cond[/b][/color] ((< i 1.0) 3)((< i 10.0) 2)((< i 100.0) 1) (t 0))) (list x 2 (if (< (abs x) 100.) 1 0 )) ) ) ) ) ) ) ) ;example (command "_TEXT" dtxcent "90" (artos (getvar 'area))) test (defun foo (l) (if (< 0.001 (car l)) (foo (setq l (mapcar ''((x) (princ (strcat "\n" (rtos x 2) " --> " ([color="blue"]artos[/color] x))) (/ x 10.)) l)) ) ) ) [color="green"];test[/color] ([color="blue"]foo[/color] '(987654321 123456789 100000000)) [color="purple"]987654321.000 --> 98765 ha 123456789.000 --> 12346 ha 100000000.000 --> 10000 ha 98765432.100 --> 9877 ha 12345678.900 --> 1235 ha 10000000.000 --> 1000 ha 9876543.210 --> 988 ha 1234567.890 --> 123 ha 1000000.000 --> 100 ha 987654.321 --> 98.8 ha 123456.789 --> 12.3 ha 100000.000 --> 10.0 ha 98765.432 --> 9.88 ha 12345.679 --> 1.23 ha 10000.000 --> 1.00 ha 9876.543 --> 0.988 ha 1234.568 --> 0.123 ha 1000.000 --> 0.100 ha 987.654 --> 988 m² 123.457 --> 123 m² 100.000 --> 100 m² 98.765 --> 98.8 m² 12.346 --> 12.3 m² 10.000 --> 10.0 m² 9.877 --> 9.9 m² 1.235 --> 1.2 m² 1.000 --> 1.0 m² 0.988 --> 1.0 m² 0.123 --> 0.1 m² 0.100 --> 0.1 m² 0.099 --> 0.1 m² 0.012 --> 0.0 m² 0.010 --> 0.0 m² 0.010 --> 0.0 m² 0.001 --> 0.0 m² 0.001 --> 0.0 m²[/color] example: ([color="blue"]defun[/color] c:atest (/ [color="red"][b]en p[/b][/color]) [color="green"]; localized variables[/color] ([color="blue"]while[/color] [color="green"]; loop if entity is selected [/color] ([color="blue"]and [/color]([color="blue"]setq[/color] en ([color="blue"]car[/color] ([color="blue"]entsel[/color] [color="purple"]"\nPick area entity.. "[/color]))) [color="green"]; select 2D entity [/color] ([color="blue"]vlax-property-available-p[/color] ([color="blue"]vlax-ename->vla-object[/color] en) 'Area) [color="green"]; check whether has 'area' property[/color] ([color="blue"]setq[/color] p ([color="blue"]getpoint[/color] [color="purple"]"\nSpecify text placement point.. "[/color])) [color="green"]; locate text insertion point [/color] ([color="blue"]entmakex[/color] ([color="blue"]list[/color] '(0 . [color="purple"]"TEXT"[/color])[b][color="red"] '( 8 . [/color][color="purple"]"leg-area"[/color][color="red"] )[/color] [/b][color="green"] ; to avoid command call [/color] ([color="blue"]cons[/color] 1 ([color="blue"]artos[/color] [color="blue"](vlax-curve-getArea[/color] en ))) [color="green"]; convert area value to string using sub function [/color] ([color="blue"]cons[/color] 10 ([color="blue"]trans[/color] p 1 0)) [color="green"]; text insertion point[/color] ([color="blue"]cons[/color] 50 (* [color="blue"]pi[/color] 0.5 )) [color="green"]; angle 90d[/color] ([color="blue"]cons[/color] 40 ([color="blue"]getvar[/color] 'textsize)) [color="green"]; text height, command: textsize[/color] ) ) ) ) ([color="blue"]princ[/color]) ) Edited July 2, 2018 by hanhphuc update test result & remove extra setq u & '( 8 . "leg-area" ) 1 Quote
BIGAL Posted July 1, 2018 Posted July 1, 2018 Hanhnphuc if you want to save micro seconds, honestly probably will not see any difference. (defun c:atest (/ en p) (setq pi2 (* pi 0.5)) (setq txts (getvar 'textsize)) ..... ..... (cons 50 pi2) ; angle 90d (cons 40 txts) ; Quote
dlanorh Posted July 2, 2018 Posted July 2, 2018 Hey all, Had a CAD user come to me complaining that some drawings this lisp (see blow) runs slow in some drawings and not others. So far, the only culprit I can see is the general segment labels. He's got about 900 of them in his drawing, and once I remove them - the lisp runs snappy. I can't figure out for the life of me what the correlation is between those labels and this lisp though. They seem completely un-related. When I set it to animate and watched it run, it hit it's biggest slog when it hits the "command" calls. Especially the layer ones. What that has to do with the general segment labels though - is beyond me. Anyone with any ideas? Here's the lisp; (defun C:a() (setq OLDLAY (getvar "CLAYER")) ;get current layer name (setq oldos(getvar "osmode")) ; get current osnap (command "layer" "set" "leg-area" "") ;Sets layer to leg-area (command "osnap" "none") ; clears osnap (command "style" "romans80I" "" "" "" "" "" "" "") ; sets style to Romans80I (defun ma() ;Defining function MA (setq b rmr); Gives the variable B a value of RMR (if (< rmr 1000) (setvar "luprec" 0)) (if (< rmr 100) (setvar "luprec" 1)) (if (< rmr 10) (setvar "luprec" 1)) (if (< rmr 1) (setvar "luprec" 1)) ) (defun ha() ;Defining the function of HA (setq b (/ rmr 10000)) ; Gives B The value of RMR divided by 10,000 (if (> b 100)(setvar "luprec" 0)) (if (< b 100)(setvar "luprec" 1)) (if (< b 10)(setvar "luprec" 2)) (if (< b 1)(setvar "luprec" 3)) ) (setq normal 0) ; Set variable normal to 0 (setq dcm (getstring "\nEnter [1] for strata or NULL for Legal :")) ; Set DCM Variable to user input (if (/= dcm "")(setq normal 1)) ; If nothing is entered DCM is set to 1 (command "area" "e" "\\"); Runs the command area - unsure of what the \\ is meant to do (setq rmr (getvar "area")) ;Sets the RMR variable to the recently selected area (if (> rmr 1000) (setq a " ha.")) ; If area is more than 1000 set variable a to HA (if (< rmr 1000) (setq a " m%%253")) ;if area is less than 1000 set variable a to M (if (= a " ha.") (ha) (ma)); If variable A equals HA then run HA else run MA (if (< rmr 1000) (setvar "luprec" 1)) ; If RMR is more than 1000 then set luprec variable to 1 (if (= normal 1)(setvar "luprec" 1)) ;If Normal is 1 then set luprec variable 1 (setq rmr (rtos b)) ; Set RMR to the value of B determined by the precision variable (setq rmr (strcat rmr a)) ; Set RMR value with either HA or MA as determined by the AREA variable (setvar "luprec" 3) ;Sets precision to 3 decimal places (SETQ DTXCENT (GETPOINT "Where ? ")); Determines where the text is placed (SETQ TEXTDEGANG "90D"); Sets text angle to 90 degrees (command "text" "c" dtxcent textdegang rmr);Prints the text on screen ;(command "osnap" "intersection,endpoint,node") (setvar "CLAYER" OLDLAY) ;reset active layer (setvar "osmode" OLDOS) ;reset active osnap (princ) ) Silvercloak This looks like an old lisp. The layer command is now trying to load a dialog box causing the slowdown. Either change the line to read (command "-layer" "set" "leg-area" "");command line version of layer or (setvar 'clayer "leg-area");avoid layer command completely Quote
BIGAL Posted July 2, 2018 Posted July 2, 2018 Good pick up dlanorh also osnap & style use setvars instead. The code has a mixture all ready. The only other thing to add is maybe check that the text style actually exists else make it. Quote
hanhphuc Posted July 2, 2018 Posted July 2, 2018 This looks like an old lisp. The layer command is now trying to load a dialog box causing the slowdown.Either change the line to read (command "-layer" "set" "leg-area" "" );command line version of layer or (setvar 'clayer "leg-area");avoid layer command completely i just notice OP code setting layer using command call. thanks another better fix.. '(0 . "TEXT") [color="red"][b]'( 8 .[/b][/color] [color="purple"][b]"leg-area"[/b][/color][color="red"][b])[/b][/color] [color="green"] ..... [/color] should be included in entmakex list. Quote
hanhphuc Posted July 2, 2018 Posted July 2, 2018 Hanhnphuc if you want to save micro seconds, honestly probably will not see any difference. (setq pi2 (* pi 0.5)) 90° Quote
Silvercloak Posted July 3, 2018 Author Posted July 3, 2018 Thanks everyone. Just got back to work this morning and see all these fantastic responses. Going to give them a try! silvercloak Quote
Silvercloak Posted July 3, 2018 Author Posted July 3, 2018 @Hanhpuc RE: What are Segments? In civil3d we have labels called general segment labels. In this particular case they're used to define the length of walls on a building. This lisp calculates the total area of a given room in the building. Quote
Silvercloak Posted July 3, 2018 Author Posted July 3, 2018 hi your lisp is related to area, but what does segment mean? example: ([color="blue"]defun[/color] c:atest (/ [color="red"][b]en p[/b][/color]) [color="green"]; localized variables[/color] ([color="blue"]while[/color] [color="green"]; loop if entity is selected [/color] ([color="blue"]and [/color]([color="blue"]setq[/color] en ([color="blue"]car[/color] ([color="blue"]entsel[/color] [color="purple"]"\nPick area entity.. "[/color]))) [color="green"]; select 2D entity [/color] ([color="blue"]vlax-property-available-p[/color] ([color="blue"]vlax-ename->vla-object[/color] en) 'Area) [color="green"]; check whether has 'area' property[/color] ([color="blue"]setq[/color] p ([color="blue"]getpoint[/color] [color="purple"]"\nSpecify text placement point.. "[/color])) [color="green"]; locate text insertion point [/color] ([color="blue"]entmakex[/color] ([color="blue"]list[/color] '(0 . [color="purple"]"TEXT"[/color])[b][color="red"] '( 8 . [/color][color="purple"]"leg-area"[/color][color="red"] )[/color] [/b][color="green"] ; to avoid command call [/color] ([color="blue"]cons[/color] 1 ([color="blue"]artos[/color] [color="blue"](vlax-curve-getArea[/color] en ))) [color="green"]; convert area value to string using sub function [/color] ([color="blue"]cons[/color] 10 ([color="blue"]trans[/color] p 1 0)) [color="green"]; text insertion point[/color] ([color="blue"]cons[/color] 50 (* [color="blue"]pi[/color] 0.5 )) [color="green"]; angle 90d[/color] ([color="blue"]cons[/color] 40 ([color="blue"]getvar[/color] 'textsize)) [color="green"]; text height, command: textsize[/color] ) ) ) ) ([color="blue"]princ[/color]) ) So I gave this a try and I'm trying to understand the code. I don't know a lot about the vla functions you're using. They never taught me that in class. Anyways, I plugged your code in and got it working but the text comes in at 0d and at the wrong scale since it comes in as not annotative... Trying to figure out how to force entmake to be annotative and not having much luck. Also - I can't figure out the line; (cons 50 (* pi 0.5) Why pi? admittedly, I haven't figured out how to force this just to do 90 degrees. Sorry I'm still very much an amateur when it comes to Lisp. I really appreciate any help you can give. Thanks, Silvercloak Quote
hanhphuc Posted July 3, 2018 Posted July 3, 2018 (edited) (cons 50 (* pi 0.5) Why pi? admittedly, I haven't figured out how to force this just to do 90 degrees. https://www.autodesk.com/techpubs/autocad/acad2000/dxf/text_dxf_06.htm Text Rotation default is 0.0 , simple ignore it, i.e: put a semicolon ';' [color="red"][b];[/b][/color][color="green"](cons 50 (* pi 0.5))[/color] autocad standard angle units in radian measured WCS X-axis counter clockwise as default i.e: 0.0 rad pi = 3.14159 = 180° pi ÷ 2 = 1.5708 rad or (* pi 0.5) , where 90° is 90 ÷ 180° = 0.50 × pi (rad) (defun dtr (deg) (* pi (/ deg 180.) )) (dtr 90.) [color="green"]; 1.5708[/color] [color="green"];example: 45°[/color] (cons 50 (dtr 45.) ) [EDIT] ...at the wrong scale since it comes in as not annotative... Trying to figure out how to force entmake to be annotative and not having much luck.. i'm not quite understand your annotative scale also not using C3D v2007 does not have annotative thingy.. but in normal case : (cons 40 (* [color="red"]scale[/color] textsize )) 'scale' can be related to any reference e.g: length or views etc.. Edited July 4, 2018 by hanhphuc Quote
Silvercloak Posted April 24, 2019 Author Posted April 24, 2019 I know this old, but one of the survey guys is complaining and asking to put this to only one decimal place. I don't code nearly enough to figure out how to change your lisp to that. Just to recap this is what I have; (defun artos (x / u i) ; Area Real To String - metric ;hanhphuc (eval (cons 'strcat (reverse (list (setq x (float x) u (if (< (setq i (/ (abs x) 1e+4)) 0.1) " m%%253" " ha")) (cons 'rtos (if (= u " ha") (list (/ x 1e+4) 2 (cond ((< i 1.0) 3)((< i 10.0) 2)((< i 100.0) 1) (t 0))) (list x 2 (if (< (abs x) 100.) 1 0 )) ) ) ) ) ) ) ) (defun c:a (/ en p) ; localized variables (while ; loop if entity is selected (and (setq en (car (entsel "\nPick area entity.. "))) ; select 2D entity (vlax-property-available-p (vlax-ename->vla-object en) 'Area) ; check whether has 'area' property (setq p (getpoint "\nSpecify text placement point.. ")) ; locate text insertion point (entmakex (list '(0 . "TEXT") '( 8 . "leg-area" ) ; to avoid command call (cons 1 (artos (vlax-curve-getArea en ))) ; convert area value to string using sub function (cons 7 "L80") (cons 10 (trans p 1 0)) ; text insertion point ;(cons 50 (* pi 0.5)) ; angle 90d (cons 40 (getvar 'textsize)) ; text height, command: textsize ) ) ) ) (princ) ) I don't even know if it's possible to reduce it to one decimal place. Thanks in advance for whatever help! Silvercloak Quote
ronjonp Posted April 24, 2019 Posted April 24, 2019 Try this: (defun artos (x / u i) ; Area Real To String - metric ;hanhphuc (eval (cons 'strcat (reverse (list (setq x (float x) u (if (< (setq i (/ (abs x) 1e+4)) 0.1) " m%%253" " ha" ) ) (cons 'rtos (if (= u " ha") (list (/ x 1e+4) 2 1) (list x 2 1) ) ) ) ) ) ) ) (defun c:a (/ en p) ; localized variables (while ; loop if entity is selected (and (setq en (car (entsel "\nPick area entity.. "))) ; select 2D entity (vlax-property-available-p (vlax-ename->vla-object en) 'area) ; check whether has 'area' property (setq p (getpoint "\nSpecify text placement point.. ")) ; locate text insertion point (entmakex (list '(0 . "TEXT") '(8 . "leg-area") ; to avoid command call (cons 1 (artos (vlax-curve-getarea en))) ; convert area value to string using sub function ;; (cons 7 "L80") (cons 10 (trans p 1 0)) ; text insertion point ;(cons 50 (* pi 0.5)) ; angle 90d (cons 40 (getvar 'textsize)) ; text height, command: textsize ) ) ) ) (princ) ) 1 Quote
ronjonp Posted April 24, 2019 Posted April 24, 2019 27 minutes ago, Silvercloak said: PERFECT! Thank you. Glad to help 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.