Jump to content

Recommended Posts

Posted

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

Posted (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 by hanhphuc
update test result & remove extra setq u & '( 8 . "leg-area" )
  • Like 1
Posted

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) ;

Posted
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

Posted

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.

Posted
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.

Posted
Hanhnphuc if you want to save micro seconds, honestly probably will not see any difference.

 

(setq pi2 (* pi 0.5))

 

90° :)

Posted

Thanks everyone. Just got back to work this morning and see all these fantastic responses. Going to give them a try!

 

silvercloak

Posted

@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.

Posted
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

Posted (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 :unsure:

 

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 by hanhphuc
  • 9 months later...
Posted

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

Posted

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)
)

 

  • Like 1
Posted

PERFECT!  Thank you.

Posted
27 minutes ago, Silvercloak said:

PERFECT!  Thank you.

Glad to help :)

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...