Progress Bar in lisp code

Progress Bar in lisp code

mhy3sx
Enthusiast Enthusiast
3,912 Views
42 Replies
Message 1 of 43

Progress Bar in lisp code

mhy3sx
Enthusiast
Enthusiast

Hi, I use this code to insert points in a drawing from a coordinate file. The problem is that when I have a lot of coordinates in the file the code is a little slow, so I want to have a progress bar to look the progress of the insert points. Can anyone help me to update the code ?

 

Thanks

0 Likes
3,913 Views
42 Replies
Replies (42)
Message 21 of 43

Sea-Haven
Mentor
Mentor

"1) I want to insert 3d points exept block points like pointsin.lsp" Just add the Z to the pt (list x y z)

 

"2)The file with coordinates have 8 decimal places for X,Y and 3 for Z and your code insert 3 to all" Not correct it reads all 8 but may only display 3. Its just the way acad works sometimes 

 

3)The point sin code call the block from a path "c:\\myblock\\point.dwg" 

 

(if (tblsearch "Block" "point")
(princ)
(setvar 'atreq 0)
(command "-insert" "c:\\myblock\\point.dwg" "0,0" 1 1 0)
(command "erase" (entlast) "")
)

 

 

4) Perhaps if not use pointsin code not need radio buttons , just convert the code to support any type of extension file ,but only comma for PENZD 

 

SeaHaven_0-1713915728682.png

Your txt file contains a comma as seperator, so this helps Getfile open correct file type.

 

0 Likes
Message 22 of 43

mhy3sx
Enthusiast
Enthusiast

Hi Sea-Haven, I can not convert your code, Is not working as I want , gives me this error every time I try to change somethig. Is not working like pointsin. The 3d points in pointsin is 3d node  not 3d blocks. Insert  very fast the points but a lot of things missing

 

Error: syntax error

 

 

1) I want to insert 3d points exept block points like pointsin.lsp

2)The file with coordinates have 8 decimal places for X,Y and 3 for Z and your code insert 3 to all

3)The point sin code call the block from a path "c:\\myblock\\point.dwg"

4) Perhaps if not use pointsin code not need radio buttons , just convert the code to support any type of extension file ,but only comma for PENZD something like this

 

(setq fname (getfiled "Select file" "" "" 0))

 

5) And I change this in ths code to work with my block

my block have POINT (for point number), ELEV (for elevation) ,DESC (for desc)

 

(foreach cogo lst
(setq
POINT (nth 0 cogo)
pt (list (atof (nth 1 cogo))(atof (nth 2 cogo)))
ELEV (nth 3 cogo)
DESC (nth 4 cogo)
)

(vla-insertblock curspace (vlax-3D-point pt) "point" 1 1 1 0)
(setq blk (vlax-ename->vla-object (entlast)))
(setq atts (vlax-invoke blk 'Getattributes))
(vlax-put (nth 0 atts) 'textstring POINT)
(vlax-put (nth 1 atts) 'textstring ELEV)
(vlax-put (nth 2 atts) 'textstring DESC)

)

 

For a first look all this missing for the code.

 

If you can do the updates I ask , to try the code again.

 

Thanks

0 Likes
Message 23 of 43

mhy3sx
Enthusiast
Enthusiast

Any other ideas?

Thanks

0 Likes
Message 24 of 43

Sea-Haven
Mentor
Mentor

There was a problem with the check for "point" I have updated the code posted previously. Please Try again.

0 Likes
Message 25 of 43

autoid374ceb4990
Collaborator
Collaborator

How slow is a "little slow"?  I loaded your code and tried it with a 30,000 point coordinate file.  It took 1min 59sec to draw all points.  Do you get a lot of information scrolling in the command area when you run the code?  If so, set "CMDECHO" to 0 (zero) and the LISP will run faster, on my computer with CMDECHO set to 0 it took 1min 10sec.

0 Likes
Message 26 of 43

Sea-Haven
Mentor
Mentor

Are you using (Command for the point creation if so look at entmake or VL way faster again, yes had like 20minutes now its similar 2 minutes doing edits to like 1000 objects 3 times.

0 Likes
Message 27 of 43

mhy3sx
Enthusiast
Enthusiast

I add this to count the progress

 

(defun pi:show-filling-progress (current total)
  (princ (strcat "\nProgress: " (rtos (/ (* 100 current) total) 2 0) "%"))
)

 

But now I am trying to fix the DCL menu I post in the beginning

 

(defun PI:GETFILEFORMAT (/ )

      (defun *error* ( / *error* dch dcl des)
        (if (and (= 'int (type dch)) (< 0 dch))
          (unload_dialog dch)
        )
        (if (= 'file (type des))
          (close des)
        )
        (if (and (= 'str (type dcl)) (findfile dcl))
          (vl-file-delete dcl)
        )

        (princ)
      ) ; end defun
     
      (cond
        ( (not
            (setq dcl (vl-filename-mktemp nil nil ".dcl")
                 des (open dcl "w")
            ) ; end setq
          ) ; end not
          (princ "\nUnable to open DCL for writing.")
        )
        ( (progn
            (foreach str '(
                            "ed : edit_box { alignment = left; width = 20; edit_width = 10; fixed_width = true;}"
                            ""
                            "pointsin : dialog { spacer; key = \"dcl\";"
                            " : boxed_column { label = \"Text Style\"; height = 1.0;}"
                            "      : radio_button { height = 1.0; width = 20; is_tab_stop = true;"
                            "        key = \"radio_button01\"; label = \"1. PNEZD (comma delimited)\";"
                            "    }" ; radio_button 
                            "      : radio_button  { height = 1.0; width = 20; is_tab_stop = true;"
                            "        key = \"radio_button02\"; label = \"2.  PNEZD (tab delimited)\";"
                            "    }" ; radio_button 
                            "      : radio_button  { height = 1.0; width = 20; is_tab_stop = true;"
                            "        key = \"radio_button03\"; label = \"3.PNEZD (white-space delimited)\";"
                            "    }" ; radio_button 
                            "      : radio_button  { height = 1.0; width = 20; is_tab_stop = true;"
                            "        key = \"radio_button04\"; label = \"4. PENZD (comma delimited)\";"
                            "    }" ; radio_button 
                            "      : radio_button  { height = 1.0; width = 20; is_tab_stop = true;"
                            "        key = \"radio_button05\"; label = \"5. PENZD (tab delimited)\";"
                            "    }" ; radio_button 
                            "      : radio_button { height = 1.0; width = 20; is_tab_stop = true;"
                            "        key = \"radio_button06\"; label = \"6. PENZD (white-space delimited)\";"
                            "    }" ; radio_button 
                            "    : row { width = 20;"
                            "      : button { key = \"OK\"; label = \"OK\"; is_default = true;"
                            "                 is_cancel = true; fixed_width = true; width = 10; }" 
                            "    }" ; end row
                            "  }" ; end dialog
                          ) ;end list
              (write-line str des)
            ) ; end foreach
            (setq des (close des)
                 dch (load_dialog dcl)
            ) ; end setq
            (<= dch 0)
          )
          (princ "\nUnable to load DCL file.")
        )
        (   (not (new_dialog "pointsin" dch))
            (princ "\nUnable to display 'pointsin' dialog.")
        )
        ( t
          (set_tile "dcl" "Select file")
		(setq FILEFORMAT1)
          (action_tile "radio_button01" "(setq FILEFORMAT 1))")
          (action_tile "radio_button02" "(setq FILEFORMAT 2))")
          (action_tile "radio_button03" "(setq FILEFORMAT 3))")
          (action_tile "radio_button04" "(setq FILEFORMAT 4))")
          (action_tile "radio_button05" "(setq FILEFORMAT 5))")
          (action_tile "radio_button06" "(setq FILEFORMAT 6))")
          (action_tile "OK" "(progn (done_dialog 1) FILEFORMAT)")
          (start_dialog)
        )
      ) ; end cond
      (*error* nil)
    (princ)
) ;_  end defun

 

Perhaps something in the

 

(action_tile 

 

is not  correct. I don't know. Can anyone help me with this?

0 Likes
Message 28 of 43

MrJSmith
Advocate
Advocate

I am surprised this hasn't been mentioned already (or maybe I missed it) but I am pretty sure you can't have a "working" progress bar in autoCAD LISP. After about 3-5 seconds of a LISP running, the CAD window in windows will typically freeze altogether, making any progress bar freeze as well while the process is still carrying out.  Lee Mac had a post somewhere explaining it more in detail, but I couldn't find it at the moment.

 

I've settled for the simple solution of posting text as a progress.  Something like divide the total by 10 and output at each milestone. This too will eventually freeze up, but it is less work to implement and gives the user a hint of where it is at in the process.

 

In terms of the program itself, others have suggested good ideas to help speed up the process. I will reiterate the most important being creating the points via VLA or entmake and limiting the amount of prints to the console as those have HUGE speed hits.  

 

 

0 Likes
Message 29 of 43

john.uhden
Mentor
Mentor

I am working on an AutoLisp progress bar right now, but I keep getting interrupted with work work.  Please be patient.

John F. Uhden

0 Likes
Message 30 of 43

autoid374ceb4990
Collaborator
Collaborator

" After about 3-5 seconds of a LISP running, the CAD window in windows will typically freeze altogether, making any progress bar freeze as well while the process is still carrying out. "

Please explain this.  I have run LISP programs for several minutes with no "freeze"

 

"Something like divide the total by 10 and output at each milestone. This too will eventually freeze up, but it is less work to implement and gives the user a hint of where it is at in the process."

So how do you know how many points are in a coordinate file without reading the entire file?

 

0 Likes
Message 31 of 43

MrJSmith
Advocate
Advocate

You can find your answers here: https://www.theswamp.org/index.php?topic=50848.0

 

As for the second question, is it involved reading the entire file? I am not sure what a "coordinate file" entails. 

0 Likes
Message 32 of 43

john.uhden
Mentor
Mentor

@autoid374ceb4990 ,

I think you do have to read the entire file first, just to count the number of lines.  Just don't try doing anything with the contents of each line yet.  You can do that the second time around...

(defun #oflines (file / fp #)
  (and
    (setq # 0)
    (setq fp (open file "r"))
    (while (read-line fp)(setq # (1+ #)))
    (close fp)
  )
  #
)

 Now there may be comment lines in the file for which you could add a test to ignore incrementing the count, but for a lot of lines it shouldn't make any significant difference... ("220,  221, whatever it takes").  Okay. now tell me the movie and the prime actor (he also played Batman).

John F. Uhden

0 Likes
Message 33 of 43

Sea-Haven
Mentor
Mentor

Look into acet-ui-progress function had something that worked will try to find. 

 

(defun wow ( / )
(setq i 1)
(acet-ui-progress-init "progress" i)
(Repeat 10000
(acet-ui-progress-safe (setq i (1+ I)))
)
)
(wow)
; may need delay here
(command "delay" 1000)
(acet-ui-progress-done)

 

 

0 Likes
Message 34 of 43

autoid374ceb4990
Collaborator
Collaborator

A coordinate file is just an ASCII file containing a list of (typically) point numbers, X, Y,Z coordinates and a point description.  These files are often used by land surveyors to transfer point coordinates between software whose native data file formats are incompatible.  There is no problem reading through this format, just takes a little time.

A typical coordinate file looks like this:

1,777574.24209,1583905.92995,0.00000,0.00000,Conc Mon 2,778069.93551,1583505.18146,0.00000,0.00000,Conc Az Mark
3,777750.40302,1584087.55786,0.00000,0.00000,rebar
4,777486.05129,1584194.78828,0.00000,0.00000,rebar
5,778634.81241,1584320.56555,0.00000,0.00000,rebar
6,778840.42440,1584378.68257,0.00000,0.00000,stone
11,777796.37573,1581207.16876,0.00000,0.00000,iron

0 Likes
Message 35 of 43

MrJSmith
Advocate
Advocate

I see. Well a progress bar necessitates you knowing roughly how much of something you are doing in order to accurately represent how much has been done VS how much is left to do. As @john.uhden pointed out, you'd probably just read how many lines the file contained, assuming each point is on a new line. You'd use the total number to increase the progress of the task. If they are not on a new line each, then you'd have to come up with some other method, like using the file size to guestimate how many coordinates might be in the file.

 

However, I still postulate that none of it matters as after 3-5 seconds, the window will freeze there by effectively killing any implemented progress bar.

0 Likes
Message 36 of 43

mhy3sx
Enthusiast
Enthusiast

I fix the dcl error. The problem was here

 

(action_tile "radio_button01" "(SETQ ANDYFORMAT (LIST (LIST \"POINT\" \"NORTH\" \"EAST\" \"ELEV\" \"DESC\") \",\" STDCOMMENT))")
          (action_tile "radio_button02" "(SETQ ANDYFORMAT(LIST (LIST \"POINT\" \"NORTH\" \"EAST\" \"ELEV\" \"DESC\") \"\t\" STDCOMMENT))")
          (action_tile "radio_button03" "(SETQ ANDYFORMAT(LIST (LIST \"POINT\" \"NORTH\" \"EAST\" \"ELEV\" \"DESC\") \"W\" STDCOMMENT))")
          (action_tile "radio_button04" "(SETQ ANDYFORMAT(LIST (LIST \"POINT\" \"EAST\" \"NORTH\" \"ELEV\" \"DESC\") \",\" STDCOMMENT))")
          (action_tile "radio_button05" "(SETQ ANDYFORMAT(LIST (LIST \"POINT\" \"EAST\" \"NORTH\" \"ELEV\" \"DESC\") \"\t\" STDCOMMENT))")
          (action_tile "radio_button06" "(SETQ ANDYFORMAT(LIST (LIST \"POINT\" \"EAST\" \"NORTH\" \"ELEV\" \"DESC\") \"W\" STDCOMMENT))")
0 Likes
Message 37 of 43

autoid374ceb4990
Collaborator
Collaborator

"However, I still postulate that none of it matters as after 3-5 seconds, the window will freeze there by effectively killing any implemented progress bar."

The link in your previous post seemed to me to that the addition of the DOSLib LISP extension may be the cause of "freeze".  I have never had that happen with a plain vanilla LISP program, but then I have never programmed a progress bar in LISP.

0 Likes
Message 38 of 43

MrJSmith
Advocate
Advocate

I've never used the DosLib expression. I did program a progress bar ~2-3 years ago and ran into that issue. Searching for a solution led me to those threads. Maybe it has changed since then.

0 Likes
Message 39 of 43

Sea-Haven
Mentor
Mentor

Mr J Smith, it depends on how many points and how you code the make object using Command is slowest, entmake and VL are massive improvements, using the dwg supplied at one stage 400 points add a block with attributes took like 1 second. 

 

In small number of points the progress bar may slow down the progress. As suggested can display "read 500 points", 1000 points and so on. 

0 Likes
Message 40 of 43

john.uhden
Mentor
Mentor

@Sea-Haven ,

I'm almost there, BUT

In order to reduce time spent progressing, I have to ignore changes in "VIEWCTR" and "VIEWSIZE", which means no zooming or panning during the primary process even with the mouse wheel, though it does work in either Modelspace or Paperspace.

Now, if that's not a concern then I may have an AutoLisp solution.  Otherwise my effort is just about worthless.

Whadya think?

John F. Uhden

0 Likes