Lisp Routines
Here is a lisp routine that calls for a list of points "xyz.tac". The file consist of 20 points. This routine works fine on autocad 2008 and on Bricscad ver 7.The bugs I found on ver 8 are: 1. PDMODE is locked. you can not change mode of points, once they are defined. 2. The ascii file consist of only 20 points. When the file is of 100 or 1000 points, there is no way of knowing if they were loaded. You have to to find out what happens. 3. Points with elvetaion that ends with "zero", i.g 325.30 what you see is only 325.3 4. Previously I mentioned that DCL files don't display characters in Hebrew. Well, it was partly corrected. Still the radio buttons don't show those characters.I think that most of the problems has to do with the LISP engine.I enclose the Lisp Routine "ptfile.lsp" and the DCL file that accompany it.Ptfile.lsp;;; Prints a pinwheel on the command line (defun Spin ( ) (setq SYMAN (cond ((= SYMAN nil) "-") ((= SYMAN "-") "\") ((= SYMAN "\") "|") ((= SYMAN "|") "/") ((= SYMAN "/") "-") ) ) (princ (strcat "\r Working... " SYMAN " ")) );end spin;;;CADALYST 01/06 Tip2083: yesno.lsp Yes/No Dialog Box (c) 2006 Nick Hofland;; Add this subroutine to ask a yes or no question;; in any program (put lsp & dcl files in search path)(defun YES-NO (strYN) (setq dcl_YN (load_dialog "yes-no.dcl")) (if (not (new_dialog "yes_no" dcl_YN)) (exit)) (set_tile "yes_no_text" strYN) (action_tile "Y_yes" "(done_dialog 1)") (action_tile "N_no" "(done_dialog 0)") (setq numYN (start_dialog)) (unload_dialog dcl_YN) (if (= numYN 0) nil T));defun(defun ddopen (koteret ext) (setQ fn "~" ; Assume a ~ fd nil ; Assume no file descriptor ) (while (= "~" fn) (if (= 1 (setq fn (getfiled koteret "" ext 4))) (setq fn (getstring "\n‰–— šŽ‰™˜ ")) ) ) ;while (if (and fn ; Got filename? ------------1 (setq fd (open fn "r")) ; ...and can read the file? ) ;and ; ...and dialog def'n is okay? (progn (set_tile "title" fn) ; Place filename in dialog title area (start_list "list_box") ; Read file's contents into list box ) ;progn ) ;if-------1;;;-------------------------------------(SetQ ly fn j (StrLen ly) n 1 endname 0 startname 1)(Repeat j (SetQ sub$ (SubStr ly n 1)) (if (or (= (Ascii sub$) 58) (= (Ascii sub$) 92)) (SetQ startname n)) (if (= (Ascii sub$) 46) (SetQ endname (1- n))) (SetQ n (1+ n)))(SetQ ly (SubStr ly (+ 1 startname)))(if (/= endname 0) (SetQ ly (SubStr ly 1 (- endname startname))))(SetQ extension (Strcase (substr fn (+ 2 endname)))));; k = Length of Number;; inc = nuber of digits after decimal point(defun DecPlace (z kk) (setq inc -1) (while (not (or (and (/= kk (setq inc (1+ inc))) (= "." (substr z (- kk inc) 1)) )))));;;------- Remove spaces left and right of string(Defun LspcR () (SetQ nn 1) (While (= (Substr rec nn 1) " ") (SetQ nn (1+ nn)) ) (SetQ rec (SubStr rec nn)) (SetQ n 1) (While (/= (Substr rec n 1) " ") ; .look for 1st space (SetQ n (1+ n)) ));==Main routin ====================(Defun C:PTfile (/ cl act size i n nn x y z z1 k k1 prec rec a fn bl blk inc dialog) (DDOPEN "Select XYZ File" "tac") (yes-no "? ìäúòìí îáìå÷éí") ;;; In hebrew (setvar "cmdecho" 0) (SetVar "Blipmode" 0) (SetQ dialog (GetVar "attdia")) (SetQ cl (GetVar "clayer")) (SetVar "attdia" 0) (If (= #knm 0) (SetQ #knm (Getreal "Scale... 1:"))) (SetVar "userR1" #knm) (SetVar "TEXTSIZE" (* #knm 0.0017)) (SetQ #htxt (* #knm 0.0017) a (/ #knm 100.0) i 0 n 1) (Setvar "HPSCALE" a) (SetVar "ltscale" a) (If (= (GetVar "PDSIZE") 0.00) (Progn (SetQ act (ukword 1 "P C N" "Point mode : Point/Cross/Nopoint " act)) (Cond ((Eq act "P") (SetQ act 32 size 2.3)) ((Eq act "C") (SetQ act 2 size 1)) ((Eq act "N") (SetQ act 0 size 1)) ) (SetVar "PDMODE" act) (SetVar "PDSIZE" (* #knm 0.0005 size)) ) ; progn ) ; if (chklayer "PRATIM") (command "LAYER" "n" "1500-BK-PTS" "c" 5 "1500-BK-PTS" "n" "1500-BK-NUM" "c" 9 "1500-BK-NUM" "n" "1500-BK-GOVA" "c" 2 "1500-BK-GOVA" "" "TEXT" "s" "standard" ^C ) (Command "layer" "s" "PRATIM" "") (while (SetQ rec (read-line fd)) (spin) (LspcR) (SetQ bl (Substr rec 1 (1- n))) (SetQ rec (SubStr rec (1+ n))) (LspcR) (SetQ y (Atof (Substr rec 1 (1- n)))) (SetQ rec (SubStr rec (1+ n))) (LspcR) (SetQ x (Atof (Substr rec 1 (1- n)))) (SetQ z (Atof (SubStr rec (1+ n)))) (SetQ x1 (+ x (* 0.002 #knm)) y1 (+ y (* 0.002 #knm)) ) (If (/= z 0) (Progn (Setq z (rtos z)) (SetQ k (Strlen z)) ;k = string length (DecPlace z k) ;k1 = nuber of digits up to decimal point (SetQ k1 (- k inc 1) z1 (atof z) prec inc ;prec = precision 2 or 3 or 4 digits z (StrCat (SubStr z 1 k1) " " (SubStr z (+ k1 2))) ) (Cond ((= prec 2) (If (= 6 k) (SetQ z (StrCat z " "))) (If (= 4 k) (SetQ z (StrCat " " z))) ) ((= prec 3) (If (= 6 k) (SetQ z (StrCat " " z))) (If (= 5 k) (SetQ z (StrCat " " z))) ) ((= prec 4) (If (= 8 k) (SetQ z (StrCat " " z))) (If (= 7 k) (SetQ z (StrCat " " z))) (If (= 6 k) (SetQ z (StrCat " " z))) ) );cond ) (SetQ z1 0.0 z " ") ) (If z (entmake (list (cons 0 "text") (cons 8 "1500-BK-GOVA") (list 10 y x z1) (cons 40 #htxt) (cons 1 z) (cons 72 4) (list 11 y x z1))) ) (SetQ i (1+ i)) ) ;While (command "layer" "s" cl "") (SetVar "Blipmode" 1) (SetVar "attdia" dialog) (SetQ fd (Close fd)) (terpri)(princ))(c:ptfile)Yes-no.dcl------------yes_no : dialog { label = " "; : boxed_column { alignment = centered; : text { key = "yes_no_text"; alignment = centered; fixed_width_font = true; is_bold = true; width = 50; } spacer_1; : row { spacer_1; : button { label = " ëï "; // Yes in hebrew key = "Y_yes"; } spacer_1; : button { label = " ìà "; // No in hebrew key = "N_no"; is_cancel = true; } spacer_1; } }}xyz.tac 3 151564.49 33260.45 380.35 4 151582.36 33254.12 379.20 5 151588.45 33252.54 380.11 6 151562.17 33246.20 380.20 7 151579.16 33240.46 379.79 8 151593.82 33239.64 380.10 9 151559.06 33227.87 378.79 10 151578.03 33230.31 379.30 11 151594.59 33224.55 378.81 12 151553.22 33210.17 379.60 13 151575.79 33219.63 377.79 14 151592.00 33211.22 376.30 15 151572.11 33209.08 379.08 16 151587.89 33198.72 377.70 17 151546.22 33193.60 379.68 18 151565.08 33194.94 379.30 19 151583.07 33186.58 379.08 20 151532.27 33178.43 379.60Raam.
Comments
-
Forgot to add a sub routine that is necessary for the previous routine. here it is:;* UKWORD User key word. DEF, if any, must match one of the KWD strings;* BIT (1 for no null, 0 for none) and KWD key word ("" for none) are same as;* for INITGET. MSG is the prompt string, to which a default string is added as;* (nil or "" for none), and a : is added.;(defun ukword (bit kwd msg def / inp) (if (and def (/= def "")) ;test for both nil and null string (setq msg (strcat "\n" msg "<" def ">: ") ;string'em with default bit ( 2 (fix (/ bit 2))) ;a default and no null bit code conflict so );setq ;this reduces bit by 1 if odd, to allow null (if (= " " (substr msg (strlen msg) 1)) ;no def, if last char is space (setq msg (strcat "\n" (substr msg 1 (1- (strlen msg))) ": ")) ;then strip space (setq msg (strcat "\n" msg ": ")) ;else msg OK ) );if,if (initget bit kwd) ;initialize the key words (setq inp (getkword msg)) ;and use the GET command (if inp inp def) ;compare the results, return appropriate value);defunRaam.
0 -
Concerning PDMODE I can already say that the range of allowed values for this system variables is a bit surprising. 4 is allowed, and 32 is allowed, but 5 is not , as are most values in between. There appears to be nothing wrong with the functionality however. PDMODE can be changed at any time. It's a display property that is not stored on any point entity so it doesn't matter if the entity was created before or after changing pdmode.kind regards,Alexander Van HeuverzwynBricsys
0 -
Dear Raam,as I said in other Forum, I will check your code, and will see what goes wrong in Bricscad+Lisp - and for sure, will get it fixed quickly.So give me a few days ... :-)Many greetingsTorsten
0 -
Dear Raam,I have checked your Lisp example - with interesting results.As forum id=7289 also refers to your same Lisp example, I will explain in full details there - please see http://www.bricsys.com/protected/en_INTL/support/forumthread.jsp?id=7289See you there,many greetingsTorsten
0 -
OK, I will remain here for discussion - as the file in forum id=7289 is a little bit different, so I will document the problems there also.No for the problems :All the problems you described originate from your Lisp file itself - there are a number of programming bugs, and a number of logical bugs. To verify, I had tested your Lisp file with full utoCAD (2000-2008) - and there all the problems were also shown.The Lisp engine in Bricscad is extremely AutoLisp compatible - so it is always a good idea, to test your Lisp files with Acad first, if possible.So lets discuss the problems step-by-step :Problem #1 function "ddopen" :(if (= 1 (setq fn (getfiled koteret "" ext 4)))(getfiled) never returns a number, only a filename string or nil, for cancel.Problem #2 function "ddopen" :added (if (not fn) (exit)) ;;### added, if file dialog was cancelledto leave the code if user cancels.Problem #3 function "ddopen" : (progn (set_tile "title" fn) ; Place filename in dialog title area (start_list "list_box") ; Read file's contents into list box )This code is out of sense - there is no DCL active, where the file lines could be listed in ??Fortunately, both Acad and Bricscad tolerate this - but iss dangerous to keep such code in the file.Problem #4 function "DecPlace" :Here, the logic for the (while...) is really bad and wrong - this caused an endless loop; mainly, this routine expects that the given string has "123.456" format, and a "." always - but the code fails for string "99" when no "." is included !This caused the endless loop then ...Fixed in attachement.Problem #5 function "LspcR" :Here, spaces shall be removed ... but the function also runs into an endless loop, if there is no space before and/or behind ...Simply, the loops should not test the string position without also testing the string length !Problem #6 function "C:PTfile" :Beside of some missing and uninitialised variables (#knm), the major problem is related to (rtos) function which is used to convert the z valuel into a string.Originally, the code uses (rtos z) - here, both unit and precision format are taken from default ... this can cause several different strings, which your code does not expect.So it is much better (and correct) to use(rtos z 2 4) to get a defined height string.Beside this, there is another most important detail : the system variable DIMZIN effects how (rtos) uses "0" characters - see DIMZIN documentation.With several DIMZIN settings, the leading and trailing zeros are suppressed - this is what happened due to your description !the Z=98.00 value was converted into string by (rtos z) as "98" - as DIMZIN was non-zero ... so all the Lisp code failed.The correct way is to save/restore DIMZIN, and to set DIMZIN=0 before (rtos z 2 4) usage ... then you will get the correct result "98.0000" ...Now we are done ... :-))As I said before, your file could not work in original AutoCAD even - due to all these problems.After corrections, Bricscad behaves exactly as AutoCAD, and your Lisp file also works fine in both systems.I have attached the fixed file here - all corrections are marked with;;###so you can simply test and verify.Many greetingswish you a nice dayTorsten
0 -
Here is one fixed file (PTFile.lsp)-----------------------;; ==============================;; Here is a Lisp routine that will draw some points with elevations. ;; the elevation of the point are converted from real numbers to a string ;; and is noted next to the point. ;; I submit here two files in which one of them has elevations that ends ;; with zeros. for instance 78.00, the other file consist of the same points ;; but with elevations that that ends with digits other then zero. ;; Try running the lisp routine. ;; The file that contains elevations of .00 will cause the computer to freeze.;; The lisp routine is as follows:;; ;;; Dialog for point list file(defun ddopen (koteret ext) (setQ fn "~" ; Assume a ~ fd nil ; Assume no file descriptor ) (while (= "~" fn) (if (= 1 (setq fn (getfiled koteret "" ext 4))) (setq fn (getstring "\nList of Files ")) ) ) (if (not fn) (exit)) ;;### added, if file dialog was cancelled (if (and fn (setq fd (open fn "r")) ; ...and can read the file? ) (progn (set_tile "title" fn) ;;### wrong here ; Place filename in dialog title area (start_list "list_box") ;;### wrong here ; Read file's contents into list box ) ) ;;;------------------------------------- (SetQ ly fn j (StrLen ly) n 1 endname 0 startname 1) (Repeat j (SetQ sub$ (SubStr ly n 1)) (if (or (= (Ascii sub$) 58) (= (Ascii sub$) 92)) (SetQ startname n)) (if (= (Ascii sub$) 46) (SetQ endname (1- n))) (SetQ n (1+ n)) ) (SetQ ly (SubStr ly (+ 1 startname))) (if (/= endname 0) (SetQ ly (SubStr ly 1 (- endname startname)))) (SetQ extension (Strcase (substr fn (+ 2 endname)))));; kk = Length of number;; inc = number of digis after decimal point;;### what happens if z = "98" ???(defun DecPlace (z kk) (setq inc -1) (while (and ;;### (not (or ...)) makes no sense here, removed; logic for compare corrected (> kk (setq inc (1+ inc))) ;;### (/= ) compare is logically wrong - kk *must be greater than (1+ inc) always. otherwise, (substr) will fail, or endless loop ! (= "." (substr z (- kk inc) 1)) ) ) (if (>= inc kk) ;;### correct return value, if nessecary (setq inc 0) inc ));;;------- Removes spaces left and right of string;;### what happens with empty line <> ???, or if no spaces left or right ???(Defun LspcR ( / slen ) (Setq slen (strlen rec)) ;;### get string length (SetQ nn 1) (While (and (< nn slen) (= (Substr rec nn 1) " ")) (SetQ nn (1+ nn)) ) (SetQ rec (SubStr rec nn)) (SetQ n 1) (While (and (< n slen) (/= (Substr rec n 1) " ")) (SetQ n (1+ n)) ));;;-------------PTFILE Main prog-------------;Drawing a point list with/without eleveation. with 2 or 3 or 4 digits after decimal point.;=========================================================================(Defun C:PTfile (/ cl act size i n nn x y z z1 k k1 prec rec a fn bl blk inc dialog) (DDOPEN "Select XYZ File" "tac") (SetQ dialog (GetVar "attdia")) (SetVar "attdia" 0) (SetQ #knm 100.0) ;;### scale was missing (SetQ #htxt (* #knm 0.0017) i 0 n 1) (command "_LAYER" "_m" "Pratim" "_c" 4 "Pratim" "") (setq olddimzin (getvar "dimzin")) ;;### DIMZIN effects (rtos) !! (SetVar "dimzin" 0) (while (SetQ rec (read-line fd)) (LspcR) (if (> (strlen rec) 0) ;;### ignore empty lines ! (progn (SetQ bl (Substr rec 1 (1- n))) (SetQ rec (SubStr rec (1+ n))) (LspcR) (SetQ y (Atof (Substr rec 1 (1- n)))) (SetQ rec (SubStr rec (1+ n))) (LspcR) (SetQ x (Atof (Substr rec 1 (1- n)))) (SetQ z (Atof (SubStr rec (1+ n)))) (SetQ x1 (+ x (* 0.002 #knm)) y1 (+ y (* 0.002 #knm)) ) (If (/= z 0) (Progn (Setq z (rtos z 2 4)) ;;### without type + precision, the z string is formatted due to system settings !! ;;### especially, DIMZIN also effects (SetQ k (Strlen z)) ;k = Length of string (DecPlace z k) ;k1 = nuber of digits left of decimal point. (SetQ k1 (- k inc 1) z1 (atof z) prec inc ;prec = number of digits right of decimal point z (StrCat (SubStr z 1 k1) " " (SubStr z (+ k1 2))) ) (Cond ((= prec 2) (If (= 6 k) (SetQ z (StrCat z " "))) (If (= 4 k) (SetQ z (StrCat " " z))) ) ((= prec 3) (If (= 6 k) (SetQ z (StrCat " " z))) (If (= 5 k) (SetQ z (StrCat " " z))) ) ((= prec 4) (If (= 8 k) (SetQ z (StrCat " " z))) (If (= 7 k) (SetQ z (StrCat " " z))) (If (= 6 k) (SetQ z (StrCat " " z))) ) ) ) (SetQ z1 0.0 z " ") ) (entmake (list (cons 0 "POINT") (list 10 y x z1) (cons 8 "Pratim"))) (entmake (list (cons 0 "TEXT") (cons 8 "Pratim") (list 10 y1 x1 z1) (cons 40 #htxt) (cons 1 bl))) (SetQ n (1+ n)) (If z (entmake (list (cons 0 "text") (cons 8 "Pratim") (list 10 y x z1) (cons 40 #htxt) (cons 1 z) (cons 72 4) (list 11 y x z1))) ) (SetQ i (1+ i)) ) ) ) (SetQ fd (Close fd)) (SetVar "dimzin" olddimzin) ;;### restore DIMZIN (SetVar "attdia" dialog) (princ));;(c:ptfile)
0 -
Dear Raam,here, some comments for the problem :"2. The ascii file consist of only 20 points. When the file is of 100 or 1000 points, there is no way of knowing if they were loaded. You have to to find out what happens. "Using your (fixed) Lisp file, I also tried the other variant, which includes the spinning wheel ...Indeed, there was a problem, that the text got not properly updated at textwindow and commandline text ... due to processor load during the loop, the text was sent to commandline/textwindow output line, but not updated by Windows MFC in synchroneous way ...This has been fixed now - and now the spinner is fine. So it will be part of next public Bricscad update (or overnext, in worst case).Once again, this was not an issue of Lisp engine :-)The same effect was present even for ADS/SDS applications ...So as I see, your PTFile.lsp runs fine now :-)One remark :currently, Bricscad is very slow when creating text entities - so if you create a large number of points+texts, you will see a remarkable difference, compared to Acad ... but this problem is also under development now.Many greetingsTorsten
0