Jump to content

Calculations with DCL, Lisp


Kris Malen

Recommended Posts

Our surveyors have asked me to create a calculation interface. I wanted to create a lisp program with an interface where the surveyors could input their measurements. They typically measure the ground level of a sewer pit and then the depth of the sewer pipes. To get the level of the sewer pipes, they subtract the ground level from their measurements.

 

However, I have some difficulties getting the interface to function. I came across code by Lee Mac and attempted to build upon it. My code is half in Dutch, 'MV' stands for Ground Level. I've attached a screenshot of my current progress. The issue is that the second calculation isn't being displayed. I would also want my outputs to have 2 decimals. 

 

 

lisp code:

 

(defun c:test ( / *error* dch dcl des mv wid diepte)
 
    (defun *error* ( msg )
        (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)
        )
        (if (and msg (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*")))
            (princ (strcat "\nError: " msg))
        )
        (princ)
    )
 
    (cond
        (   (not
                (setq dcl (vl-filename-mktemp nil nil ".dcl")
                      des (open dcl "w")
                )
            )
            (princ "\nUnable to open DCL for writing.")
        )
        (   (progn
                (foreach str
                   '(
                        "ed : edit_box"
                        "{"
                        "    alignment = left;"
                        "    width = 20;"
                        "    edit_width = 10;"
                        "    fixed_width = true;"
                        "}"
                        ""
                        "test : dialog"
                        "{"
                        "    spacer;"
                        "    key = \"dcl\";"
                        "    : ed"
                        "    {"
                        "        key = \"mv\";"
                        "        label = \"MV:\";"
                        "    }"
                        "    : ed"
                        "    {"
                        "        key = \"wid\";"
                        "        label = \"Width:\";"
                        "    }"
                        "    : ed"
                        "    {"
                        "        key = \"diepte\";"
                        "        label = \"A:\";"
                        "    }"
                        "    : row"
                        "    {"
                        "        : ed { key = \"res\"; label = \"BOK:\"; is_enabled = false; }"
                        "        : ed { key = \"res2\"; label = \"BOK2:\"; is_enabled = false; }"
                        "        : button"
                        "        {"
                        "            key = \"cal\";"
                                  
                        "            label = \"Calculate\";"
                        "        }"
                        "    }"
                        "    spacer;"
                        "    ok_only;"
                        "}"
                    )
                    (write-line str des)
                )
                (setq des (close des)
                      dch (load_dialog dcl)
                )
                (<= dch 0)
            )
            (princ "\nUnable to load DCL file.")
        )
        (   (not (new_dialog "test" dch))
            (princ "\nUnable to display 'test' dialog.")
        )
        (   t
            (set_tile "dcl" "Calculate Area")
            (action_tile "mv" "(setq mv $value)")
            (action_tile "wid" "(setq wid $value)")
            (action_tile "diepte" "(setq diepte $value)")
            (action_tile "cal"
                (vl-prin1-to-string
                   '(
                        (lambda ( / x y z)
                            (set_tile "res" "")
                            (set_tile "res2" "")
                            (cond
                                (   (or (not mv) (= "" mv))
                                    (alert "Please enter a maaiveld value.")
                                    (mode_tile "mv" 2)
                                )
                                (   (or (not wid) (= "" wid))
                                    (alert "Please enter a width value.")
                                    (mode_tile "wid" 2)
                                )
                                (   (or (not diepte) (= "" diepte))
                                    (alert "Please enter a a value.")
                                    (mode_tile "diepte" 2)
                                )
                                (   (not (setq x (distof mv)))
                                    (alert "Het Maaiveld moet een getal zijn.")
                                    (mode_tile "mv" 2)
                                )
                                (   (not (setq y (distof wid)))
                                    (alert "The width must be numerical.")
                                    (mode_tile "wid" 2)
                                )
                                (   (not (setq z (distof diepte)))
                                    (alert "The diepte must be numerical.")
                                    (mode_tile "diepte" 2)
                                )
                                (   (<= x 0.0)
                                    (alert "Het maaiveld moet groter dan nul zijn.")
                                    (mode_tile "mv" 2)
                                )
                                (   (<= y 0.0)
                                    (alert "The width must be greater than zero.")
                                    (mode_tile "wid" 2)
                                )
                                (   (<= z 0.0)
                                    (alert "The width must be greater than zero.")
                                    (mode_tile "diepte" 2)
                                )
                                
                                (   (set_tile "res" (rtos (- x y) 2)))
                                (   (set_tile "res2" (rtos (- x z) 2)))
                                    
                                  
                            )
                        
                        )
                    )
                )
            )
          (start_dialog)
        )
    )
    (*error* nil)
    (princ)
)

 

If I manage to fix this then I will try to make a leader with the outputs.  

Schermafbeelding 2024-05-16 142302.png

Schermafbeelding 2024-05-16 145628.png

Link to comment
Share on other sites

Posted (edited)

A few comments maybe just me but I just do the write dcl no need for a cond or a progn it has always worked for me, as your using vl-filename-mktemp it should work all the time as the file location is set by a default path when you install the software, I would suggest you do Options, Files, Temporay Prefix and set to a simple directory, I have D:\Acadtemp you will be amazed how much stuff ends up left behind in there. See cleanup.lsp below. 

 

I dont think you can do an Alert within a dcl command, you would have to close and reopen the dcl or could do a child dcl where it displays a message.

 

You can call a defun and do some form of calculation as a Action_tile response so call another dcl with say enter value as you have left it blank. (action_tile "mv" (check val defun))

 

(defun c:test ( / *error* dch dcl des mv wid diepte)
    (defun *error* ( msg )
        (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)
        )
        (if (and msg (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*")))
            (princ (strcat "\nError: " msg))
        )
        (princ)
    )
    (setq dcl (vl-filename-mktemp nil nil ".dcl")
          des (open dcl "w")
    )
    (foreach str
       '(
            "ed : edit_box"
            "{"
            "    alignment = left;"
            "    width = 20;"
            "    edit_width = 10;"
            "    fixed_width = true;"
            "}"
            ""
            "test : dialog"
            "{"
            "    spacer;"
            "    key = \"dcl\";"
            "    : ed"
            "    {"
            "        key = \"mv\";"
            "        label = \"MV:\";"
            "    }"
            "    : ed"
            "    {"
            "        key = \"wid\";"
            "        label = \"Width:\";"
            "    }"
            "    : ed"
            "    {"
            "        key = \"diepte\";"
            "        label = \"A:\";"
            "    }"
            "    : row"
            "    {"
            "        : ed { key = \"res\"; label = \"BOK:\"; is_enabled = false; }"
            "        : ed { key = \"res2\"; label = \"BOK2:\"; is_enabled = false; }"
            "        : button"
            "        {"
            "            key = \"cal\";"
                      
            "            label = \"Calculate\";"
            "        }"
            "    }"
            "    spacer;"
            "    ok_only;"
            "}"
        )
        (write-line str des)
    )
    (close des)
     (setq dcl_id (load_dialog dcl))
  (if (not (new_dialog "test" dcl_id))
    (exit)
  )
            (set_tile "dcl" "Calculate Area")
            (action_tile "mv" "(setq mv $value)")
            (action_tile "wid" "(setq wid $value)")
            (action_tile "diepte" "(setq diepte $value)")
            (action_tile "cal"   (strcat "(set_tile " "\"res\"" " (rtos (- x y) 2)) (set_tile " "\"res2\"" "(rtos (- x z) 2))"))
          (start_dialog)
		  (unload_dialog dcl_id)
  (vl-file-delete dcl)
    (*error* nil)
    (princ)
)

cleanup temp.lsp

Edited by BIGAL
Link to comment
Share on other sites

Hey BIGAL, thanks for your response. I have problems with the code you provided. Firstly x y and z are not defined, so I just switched them out with mv, wid and diepte. But then the problem is that I get an error on (start_dialog) that says: 

 

Exception has occurred.

bad argument type: numberp: "40" 

 

The 40 was the number that I put for 'mv'. The alerts in my code work but the problem is the second calculation doesn't show. 

 

And I don't really understand what you meant by this?

8 hours ago, BIGAL said:

You can call a defun and do some form of calculation as a Action_tile response so call another dcl with say enter value as you have left it blank. (action_tile "mv" (check val defun))

 

 

 

Schermafbeelding 2024-05-17 111224.png

calc.png

Link to comment
Share on other sites

The problem isn't the way its coded, or with using the temp folder. I think its a nice way of making a dialog tbh. The problem is here:

(cond
  [...]
  (   (set_tile "res" (rtos (- x y) 2)))
  (   (set_tile "res2" (rtos (- x z) 2)))
)

 

The first one returns true, and stops the cond.

If you want two actions, you want to put them together in a cond-item.

Like so:

(cond
  [...]
  (t
    (set_tile "res" (rtos (- x y) 2))
    (set_tile "res2" (rtos (- x z) 2))
  )
)

 

  • Thanks 1
Link to comment
Share on other sites

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