Jump to content
ALFEZ

Polyline pick and user input

Recommended Posts

ALFEZ

I have a larger program that needs the user to pick path of a polyline between two block points and so far this is what I was able to hack together for what I wanted. The problem I am still having a hard time with the basics of the logic (I believe its the logic). Could someone point me in the right direction of where I might be going wrong? 

 

;---------------------------------------------------------------------------------
;                           Polyling place function                                 
;---------------------------------------------------------------------------------
; Polyline place  -  ALFEZ
; Create new layer if it dosen't exist.
; Polyline starts at blk1 point.
; Prompts user to pick points
; If point is not good user can undo (up to blk1 point) 
; when user hits enter polyline completes at blk2
;---------------------------------------------------------------------------------
(defun :pickpoly (blk1 blk2 / done out ens ben)
							; blk1 - block one data 
							; blk2 - block two data 
							;  - 
							;  - 
							;  - 

; make new layer if it doesnt exist
		(vl-cmdf "_.LAYER" "_Thaw" "HIDDEN" "_Make" "HIDDEN" "")
		(setvar 'attdia 0)
		(setvar 'attreq 0)
; start polyline with red colour 
		(setvar 'cecolor "1")
		(setvar 'cmdecho 0)
		(vl-cmdf "_PLINE" "_non" (if (= (car blk1) "COMBINER") (setq pnt (last blk1)) (setq pnt (caddr blk1))))
	(progn  ; pick route for polyline (user input to the destination block)
		(setq pnt (getpoint "\nNext point: " pnt))
		(command "_non" pnt)
    (while (progn
			(initget "Undo")
			(setq pnt
				(getpoint "\nNext point [Undo] <exit>: ")
		   );setq
	     );progn
      (cond ((= pnt "Undo")
				(command "erase" "last" ""))
			((command "_non" pnt))
	    );cond
      );while
			(T
			(command "_non" (caddr blk2) "")
			);T
	T) ; progn
	(setq pen (entlast))     ; get pline entity name
	(vl-cmdf "_.CHPROP" pen "" "_Color" 3 "")
	(setvar 'attdia 0)
	(setvar 'attreq 0)
out
); defun

Feel free to point me to other posts or resources that will help me.

Share this post


Link to post
Share on other sites
ALFEZ

So after a little help from another forum, I was suggest to go towards changing my code for the user input for the bellow:

		(command "pline" "_non" (if (= (car blk1) "COMBINER") (setq pnt (last blk1)) (setq pnt (caddr blk1))))
			(while (eq 1 (getvar "cmdactive"))
				(prompt "\nNext point [Undo] <exit>: ")
				(command pause)
			)

My problem now is to get the last point when the user hits enter to go to the point i want. 

Share this post


Link to post
Share on other sites
pkenewell

Simple:

1) When the user presses enter, Prompt for the 2nd block using (setq en (entsel "\nSelect 2nd Block: ")). NOTE: Don't end the command - leave it going.

2) Extract the insertion point of the block from the entity data via (set ip (cdr (assoc 10 (entget (car en))))).

3) Add to the running pline command and end it (command ip "")

 

EDIT: Hold that thought. Didn't realize that you already had the points. I will come up with something better for you.

 

for your current version - do this instead:

(command "._pline" "_non" (if (= (car blk1) "COMBINER") (setq pnt (last blk1)) (setq pnt (caddr blk1))))
(initget "Undo Exit")
(while (and (setq pt (getpoint "\nNext Point [Undo/Exit] <Exit>: "))(/= pt "Exit"))
   (if (= pt "Undo")(command "_Undo")(command "_non" pt)
   (initget "Undo Exit")
)
(command "_non" (if (= (car blk2) "COMBINER") (setq pnt (last blk2)) (setq pnt (caddr blk2))) "")

 

Edited by pkenewell

Share this post


Link to post
Share on other sites
pkenewell

Better Yet - consider this code. Alter as you need. No error checking or layer setup, but will give you an alternative idea.

 

EDIT: Corrected issue with "Undo" option (wasn't removing last point from the list). Updated code.

EDIT2: Slightly more refined version and correction (multiple "Undo" calls would fail). Updated code.

 

(defun c:PickPoly (/ en lp np pl)
   (if (setq en (entsel "\nSelect 1st Block: "))
       (progn
          (setq lp (cdr (assoc 10 (entget (car en)))) pl (list lp))
          (initget "Undo Exit")
          (while (and (setq np (Getpoint lp "\nSelect Next Point [Undo/Exit] <Exit>: "))(/= np "Exit"))
              (if (= (type np) 'LIST)
                 (progn
                    (grdraw lp np -1)
                    (setq pl (cons np pl) lp np)
                 )
                 (if (> (length pl) 1)
                    (progn
                       (grdraw (cadr pl) (car pl) -1)
                       (setq pl (cdr pl)
                             lp (car pl)
                       )
                    )
                    (princ "\nNothing to Undo.")
                 )
              )
              (Initget "Undo Exit")
          )
          (if (setq en (entsel "\nSelect 2nd Block: "))
             (progn
                (setq pl (cons (cdr (assoc 10 (entget (Car en)))) pl))
                (grdraw lp (car pl) -1)
             )
          )
          (setq pl (reverse pl))
       )
   )
   (if pl
      (progn
         (redraw)
         (command "._pline")
         (mapcar '(lambda (x)(command "_non" x)) pl)
         (command "")
      )
   )
   (princ)
)

 

Edited by pkenewell

Share this post


Link to post
Share on other sites
ALFEZ

Thank you @pkenewell I have been playing with my code a good part of the day and had got something similar at one point. I suggested a short and sweet way by someone on the autodesk forum. I am testing it now if it works I will post the solution and a link to the other forum so the person that gave me the simple solution gets the credit!.

 

Share this post


Link to post
Share on other sites
BIGAL

Pretty sure suggested this way at another site, when pick a point then want to pick another point use (getpoint Pt1 "pick next point') this will show a "temporary line" from Pt1 so you can see what is  going on. I would do the pline task after selecting points, yes it can be points. Rather than before. you can make a list of points then create pline.

 

The method I would use is pick a point using say nearest to blk1 you can override this, will give a point, you uses ssget "F" (list pt1 pt2) pts which are a used as a dummy crossing selection which will find the block. Test block name if ok then draw pline pts use say nearest to pick last check block again.

 

Example code

(setvar 'osmode 512)
(setq pt1 (getpoint "Pick point on block1"))
(setq pt2 (getpoint "pick point on block2"))
(setq ss (ssget "F" (list (polar pt1 (* pi 0.25) 1) (polar pt1 (* 1.25 pi) 1))))
(setq blkname1 (cdr (assoc 2 (entget (ssname ss 0)))))
(setq ss (ssget "F" (list (polar pt2 (* pi 0.25) 1) (polar pt2 (* 1.25 pi) 1))))
(setq blkname2 (cdr (assoc 2 (entget (ssname ss 0)))))
(command "line" pt1 pt2 "")
(alert (strcat "Drew a line from pt1 - pt2 \n \n Block 1 is " blkname1 "\n \n Block 2 is " blkname2))

 

Share this post


Link to post
Share on other sites
ALFEZ

So this is what I was looking for in the ended. Thank you everyone for the guidance!

Polyline fun. It was not the destination but the journey!

;---------------------------------------------------------------------------------
;                           Polyling place function                                 
;---------------------------------------------------------------------------------
; Polyline place  -  BeekeeCZ, SeeMSixty7,  ALFEZ
; Create new layer if it dosen't exist.
; Polyline starts at blk1 point.
; Prompts user to pick points
; If point is not good user can undo (up to blk1 point) 
; when user hits enter polyline completes at blk2
;---------------------------------------------------------------------------------
(defun :pickpoly (blk1 blk2 / out ens pnt)
							; blk1 - block one data input (blockname entname entselpoint insertpoint)
							; blk2 - block two data input (blockname entname entselpoint insertpoint)
							;  ens - first insertion point of pline 
							;  pnt - point picked
							;  - 


		(vl-cmdf "_.LAYER" "_Thaw" "HIDDEN" "_Make" "HIDDEN" "")
		(setvar 'attdia 0)
		(setvar 'attreq 0)
; start polyline with red colour (hopefully, the user will have it start near or on the block perimeter) 
		(setvar 'cecolor "1")
		(setvar 'cmdecho 0)
		(if (= (car blk1) "COMBINER") (setq pnt (last blk1)) (setq pnt (caddr blk1)))
		(vl-cmdf "_PLINE" "_non" pnt)
	(progn
			(while
				(progn ; your while condition is what keeps you in the while loop
					(initget "Undo")
					(setq pnt (getpoint "\nNext point [Undo]: "  (getvar 'lastpoint)))
					;Deleted Exit option as when they simply hit enter the command moves on and exits the while statement
				) ;This progn statement ends with a value as long as user picks a point or provides input, once user hist enter it returns nil and exits loop
				(if (= pnt "Undo")
					(command "_Undo")
					(command "_non" pnt)
				) ;if
			);while
			(command "_non" (last blk2) "")
		)
	(setq pen (entlast))     ; get pline entity name
	(vl-cmdf "_.CHPROP" pen "" "_Color" 3 "")
	(setvar 'attdia 0)
	(setvar 'attreq 0)
out
); defun
;---------------------------------------------------------------------------------

 

 

Share this post


Link to post
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
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

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