Jump to content

DCL and Lisp to insert point and move point


EricDevault

Recommended Posts

Here's my challenge:

I need a routine that will prompt the user to insert a point at an intersection and then move that point a given distance from the edit_box value. There are currently 4 buttons to select to move the point, UP, LEFT, RIGHT and DOWN and also the standard OK, Cancel.

Currently my code will insert a point and the form shows to prompt the user the move distance, but after that I am going in circles trying to figure out how to set the value from the edit_box. Also the value needs to be in inches, not sure how to go about that other than a (val/12). The last piece of the puzzle will be to insert a dimension from the original insert point intersection to the points new location and then loop back to the beginning where we prompted the user to insert a point at an intersection. Thanks for anyone's input I really appreciate it.

The code so far:

DCL:

//DCL CODING STARTS HERE
move_pt

: dialog

{

label = "Move Points";

: column {
: row {

: button {label = "UP"; key = "up";
		width = 6;}

}
}

: column {
: row {
: button {label = "LEFT"; key = "left";
		 width = 6;}
: edit_box {key = mval; width = 7; value = "";
		alignment = centered;}
: button {label = "RIGHT"; key = "right";
		 width = 6;}

}
}

: column {
: row {

: button {label = "DOWN"; key = "down";
		width = 6;}
}
}

: column {
: row {
	
: button {label = "OK"; key = "accept";	mnemonic = "O";
		width = 6; is_default = true;}
: button {label = "Cancel"; key = "cancel";	mnemonic = "c";
		width = 6;}
	
}
}

}

 

Lisp:

(defun c:edgept ()
;define the function

(defun saveVars()
(setq mval( distof (get_tile "mval")))
)

(defun doButton(a)
(cond

((= a 1)(command "._move" (entlast) "" (list 0 (/ mval 12) 0) ""))
((= a 2)(command "._move" (entlast) "" (list [color="red"]((* mval -1)/ 12)[/color] 0 0) ""))
((= a 3)(command "._move" (entlast) "" (list (/ mval 12) 0 0) ""))
((= a 4)(command "._move" (entlast) "" (list 0 [color="red"]((* mval -1)/ 12)[/color] 0) ""))
)
)

;********************************************************

(setvar "CLAYER" "COVER")


(setq pt (getpoint "\Choose intersection you are measuring from: "))
(command "._point" pt)


(setq dcl_id (load_dialog "move_pt.dcl"))
    (if (not (new_dialog "move_pt" dcl_id))
 (exit)
    );end if

(action_tile
      "cancel"
      "(done_dialog 1)")

(action_tile
"up" "(saveVars) (doButton 1)(done_dialog)")

(action_tile
"left" "(saveVars) (doButton 2)(done_dialog)")

(action_tile
"right" "(saveVars) (doButton 3)(done_dialog)")

(action_tile
"down" "(saveVars) (doButton 4)(done_dialog)")	


(start_dialog)					;start dialog
(unload_dialog dcl_id)

(if(= done_diaglog 1)
           (princ "\n  cancelled!")
         )






(princ)
)
(princ)

 

Edit: I have updated the code above, I am stuck on the negative value of "mval" in red.

And still need a dimension from origin to new pt location.

Edited by EricDevault
Updated code
Link to comment
Share on other sites

Hi,

 

Just give a brief info about the four buttons .

For example , if a user pressed Up , where is the new location or the new coordinates that the Point object should be moved to ? then as well as the rest of the buttons .

Link to comment
Share on other sites

You can make a block for your point , but point a point will do , select it in your program with entlast , store your distance value in a global value or one of autocads user variables

 

USERI1–5 Stores and retrieves integer values

USERR1–5 Stores and retrieves real numbers

USERS1–5 Stores and retrieves text string data

 

and then when user presses up , use move (entlast) @ your distance

 

When you store both your insertion point and your new 'polar' point you can dimension it.

 

Good luck

 

gr. Rlx

Link to comment
Share on other sites

Hi,

 

Just give a brief info about the four buttons .

For example , if a user pressed Up , where is the new location or the new coordinates that the Point object should be moved to ? then as well as the rest of the buttons .

 

Tharwat,

Absolutly.

The four buttons will move the point that the user inserted from original insertion point to a point "example" +15 along the y axis if up was pressed, +15 along the x axis if right was pressed, -15 along the y axis if down was pressed, and -15 along the x axis if left was pressed, assuming the user typed 15 in the edit_box. I edited the code above

(defun doButton(a)
(cond

((= a 1)(command "._move" (entlast) "" (list 0 (/ mval 12) 0) ""))
((= a 2)(command "._move" (entlast) "" (list (/ (* mval -1) 12) 0 0) ""))
((= a 3)(command "._move" (entlast) "" (list (/ mval 12) 0 0) ""))
((= a 4)(command "._move" (entlast) "" (list 0 (/ (* mval -1) 12) 0) ""))

So actually all my buttons are working now, I just need the dimension portion.

Lastly, and I realize this was added late in the game, but I am wondering how hard it would be to then connect a line through all the points.

Link to comment
Share on other sites

You can make a block for your point , but point a point will do , select it in your program with entlast , store your distance value in a global value or one of autocads user variables

 

USERI1–5 Stores and retrieves integer values

USERR1–5 Stores and retrieves real numbers

USERS1–5 Stores and retrieves text string data

 

and then when user presses up , use move (entlast) @ your distance

 

When you store both your insertion point and your new 'polar' point you can dimension it.

 

Good luck

 

gr. Rlx

 

I am interested in seeing how this can be applied, I will try to work with this, thanks.

Link to comment
Share on other sites

Clear enough , you don't need that dobutton function in every action tile although the list of new coordinates is wrong ,anyway I will post the correct codes tomorrow morning since it's late here now.

 

One more thing is that you have lots of extra column & row functions that needs to be removed plus the key word for the edit box must be a string.

Link to comment
Share on other sites

Clear enough , you don't need that dobutton function in every action tile although the list of new coordinates is wrong ,anyway I will post the correct codes tomorrow morning since it's late here now.

 

One more thing is that you have lots of extra column & row functions that needs to be removed plus the key word for the edit box must be a string.

 

I agree it needs cleaned up a lot, this was the 7-8th pass at it and I admit I'm not the cleanest haha. Any help is much appreciated.

Link to comment
Share on other sites

Can you avoid the use all together of a dcl why not CHX CHY just simple lisps and supply a positive or negative value of amount to move you can have factor also /12 etc if required. Inside a loop just keep picking objects to move, pretty easy to change to a get pt first.

 

(defun c:PTX ( / Pt mvamount))
(setq oldsnap (getvar "osmode'))
(setq pt (getpoint "pick point"))
(setvar "osmode" 0)
(command "point" pt)
(setq mvamount (getreal "Enter value"))
(Command "Move" "L" "" (list 0 0 0) (list mvamount 0 0))
(setvar "osmode" oldsnap)
)

Link to comment
Share on other sites

Can you avoid the use all together of a dcl why not CHX CHY just simple lisps and supply a positive or negative value of amount to move you can have factor also /12 etc if required. Inside a loop just keep picking objects to move, pretty easy to change to a get pt first.

 

(defun c:PTX ( / Pt mvamount))
(setq oldsnap (getvar "osmode'))
(setq pt (getpoint "pick point"))
(setvar "osmode" 0)
(command "point" pt)
(setq mvamount (getreal "Enter value"))
(Command "Move" "L" "" (list 0 0 0) (list mvamount 0 0))
(setvar "osmode" oldsnap)
)

 

I would like to use a dcl as this will be used by individuals without any CAD training, basically I need to write all the upfront commands and variables while keeping a clean interface. This is just one component in the process. Remember they will not know nor have access to all the commands. It's like the first step in a custom product, the final stage will be designed by skilled technicians.

Link to comment
Share on other sites

Try this program and let me know how it works with you .

 

DCL codes:

 

move_pt : dialog { label = "Move Points";
   : button {
   		label = "UP";
   		key = "up";
   		width = 6;}
   : row {
   : button {
   		label = "LEFT";
   		key = "left";
   		width = 6;}
   : edit_box {
   		key = "mval";
   		width = 7;}
   : button {
   		label = "RIGHT";
   		key = "right";
   		width = 6;}
   	}
   : button {
   		label = "DOWN";
   		key = "down";
   		width = 6;}
   : row {
   : button { 
   		label = "OK";
   		key = "accept";
   		mnemonic = "O";
   		width = 8;
   		is_default = true;}
   : button {
   		label = "Cancel";
   		key = "cancel";
   		mnemonic = "c";
   		width = 8;
   		is_cancel = true;
   		}    
}}

 

(defun c:test (/ pt obj id e p)
 ;; Tharwat 14.07.2015	;;
 (if (tblsearch "LAYER" "COVER")
   (setvar "CLAYER" "COVER")
   )
 (if (zerop (getvar 'pdmode))
   (setvar 'pdmode 3)
   )
 (if (setq
       pt (getpoint "\nChoose intersection you are measuring from: ")
       )
   (setq obj (entmakex (list '(0 . "POINT") (cons 10 pt))))
   )
 (vla-regen (vla-get-activedocument (vlax-get-acad-object))
            acallviewports
            )
 (if (and obj
          (< 0 (setq id (load_dialog "move_pt.dcl")))
          (new_dialog "move_pt" id)
          )
   (progn
     (setq e (entget obj)
           p (cdr (assoc 10 e))
           )
     (defun number-p ()
       (or (eq (get_tile "mval") "")
           (zerop (atoi (get_tile "mval")))
           )
       )
     (action_tile
       "up"
       "(if (number-p)(progn
                        (mode_tile \"mval\" 2)
                        (alert \"Contents of Edit box is either not numbers or null !\"))
                        (progn
                           (entmod (append e (list (cons 10 (list (car p) (+ (cadr p) (read (get_tile \"mval\"))) (caddr p))))))
                           (done_dialog))) "
       )
     (action_tile
       "left"
       "(if (number-p)(progn
                        (mode_tile \"mval\" 2)
                        (alert \"Contents of Edit box is either not numbers or null !\"))
                           (progn
                           (entmod (append e (list (cons 10 (list (- (car p) (read (get_tile \"mval\"))) (cadr p) (caddr p))))))
                           (done_dialog)))"
       )
     (action_tile
       "right"
       "(if (number-p)(progn
                        (mode_tile \"mval\" 2)
                        (alert \"Contents of Edit box is either not numbers or null !\"))
                           (progn
                           (entmod (append e (list (cons 10 (list (+ (car p) (read (get_tile \"mval\"))) (cadr p) (caddr p))))))
                           (done_dialog)))"
       )
     (action_tile
       "down"
       "(if (number-p)(progn
                        (mode_tile \"mval\" 2)
                        (alert \"Contents of Edit box is either not numbers or null !\"))
                           (progn
                           (entmod (append e (list (cons 10 (list (car p) (- (cadr p) (read (get_tile \"mval\"))) (caddr p))))))
                           (done_dialog)))"
       )
     (action_tile "accept" "(done_dialog)")
     (action_tile "cancel" "(done_dialog)")
     (start_dialog)
     (unload_dialog id)
     )
   (if (< 0 id)
     (unload_dialog id)
     )
   )
 (princ)
 )(vl-load-com)

Link to comment
Share on other sites

This is a different approach using a global library defun that you preload you can use it in any routine this is an example for 2 questions, the code previously posted elsewhere was for 1 2 or 3 line input. It dynamically creates the dcl so no hard coding required.

 

 

; 2 line dcl save as a library function a nd autoload
; sample code (ah:getval2 "line 1" 4 3 "line2" 8 7)

(defun AH:getval2 (title1 width1 limit1 title2 width2 limit2 / fo)
;(setq fname (strcat (getvar "SAVEFILEPATH") "\\getval2.dcl"))
(setq fname (strcat (getenv "TEMP") "\\getval2.dcl"))
(setq fo (open fname "w"))
(write-line "ddgetval2 : dialog {" fo)
(write-line " : column {" fo)
(write-line ": edit_box {" fo)
(write-line (strcat "    key = " (chr 34) "key1" (chr 34) ";") fo)
(write-line  (strcat " label = "  (chr 34) title1 (chr 34) ";" ) fo)
(write-line (strcat "     edit_width = " (rtos width1 2 0) ";" ) fo)
(write-line (strcat "     edit_limit = " (rtos limit1 2 0) ";" ) fo)
(write-line "   is_enabled = true ;" fo)
(write-line "    }" fo)
(write-line "spacer_1 ;" fo)
(write-line ": edit_box {" fo)
(write-line (strcat "    key = " (chr 34) "key2" (chr 34) ";") fo)
(write-line (strcat " label = "  (chr 34) title2 (chr 34) ";"  ) fo)
(write-line (strcat "     edit_width = " (rtos width2 2 0) ";" ) fo)
(write-line (strcat "     edit_limit = " (rtos limit2 2 0) ";" ) fo)
(write-line "   is_enabled = true ;" fo)
(write-line "    }" fo)
(write-line "    }" fo)
(write-line "spacer_1 ;" fo)
(write-line "ok_only;}" fo)
(close fo)

; code part
(setq dcl_id (load_dialog  fname))
(if (not (new_dialog "ddgetval2" dcl_id))
(exit))
(mode_tile "key1" 3)
(action_tile "key1" "(setq val1 $value)")
(mode_tile "key2" 3)
(action_tile "key2" "(setq val2 $value)")

(start_dialog)
(done_dialog)
(unload_dialog dcl_id)
; returns the value of val1 and val2 as strings
)

 

(ah:getval2 "MOVE IN X OR Y enter value X or Y" 4 3  "ENTER OFFSET VALUE -VE OR +VE <L-R U-D>" 8 7)
(IF (= VAL1 (STRCASE "X"))(c:ptx)(c:pty))

(defun c:PTX ( / Pt)
(setq oldsnap (getvar "osmode'))
(setq pt (getpoint "pick point"))
(setvar "osmode" 0)
(command "point" pt)
(Command "Move" "L" "" (list 0 0 0) (list (rtos val2) 0 0))
(setvar "osmode" oldsnap)
)

(defun c:PTY ( / Pt )
(setq oldsnap (getvar "osmode'))
(setq pt (getpoint "pick point"))
(setvar "osmode" 0)
(command "point" pt)
(Command "Move" "L" "" (list 0 0 0) (list 0 (rtos val2) 0))
(setvar "osmode" oldsnap)
)

Link to comment
Share on other sites

Try this program and let me know how it works with you .

 

DCL codes:

 

move_pt : dialog { label = "Move Points";
   : button {
   		label = "UP";
   		key = "up";
   		width = 6;}
   : row {
   : button {
   		label = "LEFT";
   		key = "left";
   		width = 6;}
   : edit_box {
   		key = "mval";
   		width = 7;}
   : button {
   		label = "RIGHT";
   		key = "right";
   		width = 6;}
   	}
   : button {
   		label = "DOWN";
   		key = "down";
   		width = 6;}
   : row {
   : button { 
   		label = "OK";
   		key = "accept";
   		mnemonic = "O";
   		width = 8;
   		is_default = true;}
   : button {
   		label = "Cancel";
   		key = "cancel";
   		mnemonic = "c";
   		width = 8;
   		is_cancel = true;
   		}    
}}

 

(defun c:test (/ pt obj id e p)
 ;; Tharwat 14.07.2015	;;
 (if (tblsearch "LAYER" "COVER")
   (setvar "CLAYER" "COVER")
   )
 (if (zerop (getvar 'pdmode))
   (setvar 'pdmode 3)
   )
 (if (setq
       pt (getpoint "\nChoose intersection you are measuring from: ")
       )
   (setq obj (entmakex (list '(0 . "POINT") (cons 10 pt))))
   )
 (vla-regen (vla-get-activedocument (vlax-get-acad-object))
            acallviewports
            )
 (if (and obj
          (< 0 (setq id (load_dialog "move_pt.dcl")))
          (new_dialog "move_pt" id)
          )
   (progn
     (setq e (entget obj)
           p (cdr (assoc 10 e))
           )
     (defun number-p ()
       (or (eq (get_tile "mval") "")
           (zerop (atoi (get_tile "mval")))
           )
       )
     (action_tile
       "up"
       "(if (number-p)(progn
                        (mode_tile \"mval\" 2)
                        (alert \"Contents of Edit box is either not numbers or null !\"))
                        (progn
                           (entmod (append e (list (cons 10 (list (car p) (+ (cadr p) (read (get_tile \"mval\"))) (caddr p))))))
                           (done_dialog))) "
       )
     (action_tile
       "left"
       "(if (number-p)(progn
                        (mode_tile \"mval\" 2)
                        (alert \"Contents of Edit box is either not numbers or null !\"))
                           (progn
                           (entmod (append e (list (cons 10 (list (- (car p) (read (get_tile \"mval\"))) (cadr p) (caddr p))))))
                           (done_dialog)))"
       )
     (action_tile
       "right"
       "(if (number-p)(progn
                        (mode_tile \"mval\" 2)
                        (alert \"Contents of Edit box is either not numbers or null !\"))
                           (progn
                           (entmod (append e (list (cons 10 (list (+ (car p) (read (get_tile \"mval\"))) (cadr p) (caddr p))))))
                           (done_dialog)))"
       )
     (action_tile
       "down"
       "(if (number-p)(progn
                        (mode_tile \"mval\" 2)
                        (alert \"Contents of Edit box is either not numbers or null !\"))
                           (progn
                           (entmod (append e (list (cons 10 (list (car p) (- (cadr p) (read (get_tile \"mval\"))) (caddr p))))))
                           (done_dialog)))"
       )
     (action_tile "accept" "(done_dialog)")
     (action_tile "cancel" "(done_dialog)")
     (start_dialog)
     (unload_dialog id)
     )
   (if (< 0 id)
     (unload_dialog id)
     )
   )
 (princ)
 )(vl-load-com)

 

I had to remove the instances of

;(vla-regen (vla-get-activedocument (vlax-get-acad-object))
            ;acallviewports
           ; )
;(vl-load-com)

and also I'm not sure how to change it to divide "mval" by 12. Additionally, what are the old values of the point and what are the new values of the point?

This is definitely written better than mine, but dissecting it is not easy.

Here's what I need, insert point, move point in a given direction and distance based on the dcl (we have those two covered) then give a dimension from the original insertion point to the new point, and finally connect a line through all the points.

The last part about connecting a line through all the points came in later and might not be possible.

Link to comment
Share on other sites

and also I'm not sure how to change it to divide "mval" by 12.

Example for one and you can do for the rest .

 

(/ (read (get_tile \"mval\")) 12.)

Link to comment
Share on other sites

I am a little confused you have commented that you want to use it for multiple points, you can do it so easy press F8 this turns ortho on, you pick your start point then just drag using mouse in the required direction, then simply type in the distance required, you can just keep going drawing square line. If you use the pline option then it would be easy to auto dim the pline.

 

; have a look at this try it with ortho on and dragging mouse typing distance its just so quick 2 lines of code compare to above
(command "_pline") 
(while (= (getvar "cmdactive") 1 ) (command pause))

Link to comment
Share on other sites

I am a little confused you have commented that you want to use it for multiple points, you can do it so easy press F8 this turns ortho on, you pick your start point then just drag using mouse in the required direction, then simply type in the distance required, you can just keep going drawing square line. If you use the pline option then it would be easy to auto dim the pline.

 

; have a look at this try it with ortho on and dragging mouse typing distance its just so quick 2 lines of code compare to above
(command "_pline") 
(while (= (getvar "cmdactive") 1 ) (command pause))

 

The user will start with a grid and for simplicity sake let's say it is a 3x3 grid 18x36. So that's 6 rows, 12 columns. The point(node) is a layout of each perimeter point as it crosses either a vertical or horizontal line of the grid. In order to get the location of that point a measurement from the closest vertex of the grid to the edge is needed. So the user picks the vertex measured from, the distance to the edge point, and then the direction from the vertex that point will lay. Again this is just one part of the process to layout the points along the perimeter. I have already automated the grid layout which 9 times out of 10 will not be a simple 3x3 grid at a given size.

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