PDA

View Full Version : Help with ssget (Part II of cleaning up an old routine)


tflaherty
2005-05-18, 05:58 PM
One piece of the old routine that was never finished enabled the user to select a cabinet door and replace it with a bank of drawers. All he got to was prompting the user to select the door to replace, creating a selection set of those objects then erasing them.

Here's the code he had in place:

(initget "Yes No")
(setq drwrans (getkword "nReplace cabinet door with drawers? [Yes/No] <Yes> "))
(if (or (= drwrans "Yes") (not drwrans))
(progn
(setvar "cmdecho" 0)
(princ "nSelect cabinet door to replace: ")
(setq drwrset (ssget)
drwrnum (getint "nSpecify number of drawers: "))
(command "erase" drwrset "")))
(princ)

The response I get at the command line is this:

Replace cabinet door with drawers? [Yes/No] <Yes>
Select cabinet door to replace:
Select objects:

My first question is; is there a way to get rid of the double prompt to select objects?

My second question is; what command/function do I need to look at to find out the lower most left coordinate and the upper most right coordinate of the entities selected?

Thanks for all you help in advance.

scwegner
2005-05-18, 06:39 PM
You can't avoid the double prompt with ssget unless you just want the plain "Select objects:" that ssget uses. You may be able to use entsel instead which allows you to specify the prompt and would allow you to go straight into the database to get the corners of you rectangle.

Opie
2005-05-18, 07:17 PM
If your cabinet door is a single entity (ie: polyline) I would recommend the entget solution scwegner proposes.

However, if your cabinet door is not a single entity you can try the ssget function with the "cp" option with a point list. The following code is a replacement of two of your lines of code shown below.

(setq LCRNR (getpoint "\nPick lower left corner of cabinet door: ")
RCRNR (getcorner LCRNR
"\nPick upper right corner of cabinet door: "
)
PT_LIST (list RCRNR
(list (car RCRNR) (cadr LCRNR))
LCRNR
(list (car LCRNR) (cadr RCRNR))
)
DRWRSET (ssget "cp" PT_LIST)
drwrnum (getint "nSpecify number of drawers: ")
)

Place the above code in place of

(princ "nSelect cabinet door to replace: ")
(setq drwrset (ssget)
drwrnum (getint "nSpecify number of drawers: "))


One piece of the old routine that was never finished enabled the user to select a cabinet door and replace it with a bank of drawers. All he got to was prompting the user to select the door to replace, creating a selection set of those objects then erasing them.

Here's the code he had in place:

(initget "Yes No")
(setq drwrans (getkword "nReplace cabinet door with drawers? [Yes/No] <Yes> "))
(if (or (= drwrans "Yes") (not drwrans))
(progn
(setvar "cmdecho" 0)
(princ "nSelect cabinet door to replace: ")
(setq drwrset (ssget)
drwrnum (getint "nSpecify number of drawers: "))
(command "erase" drwrset "")))
(princ)

The response I get at the command line is this:

Replace cabinet door with drawers? [Yes/No] <Yes>
Select cabinet door to replace:
Select objects:

My first question is; is there a way to get rid of the double prompt to select objects?

My second question is; what command/function do I need to look at to find out the lower most left coordinate and the upper most right coordinate of the entities selected?

Thanks for all you help in advance.
hth

tflaherty
2005-05-18, 09:32 PM
OK, I'm getting close, I think. This is what I've don to clean up the drawer draw section of the routine. The first "getkword" does not recognize the defualt response of "Yes" when I hit the enter key, but it does recognize "Y" or "N". Also, when it gets to the point of prompting for number of additional drawers it cancels out and takes me back to the command line.


(initget "Yes No")
(setq
DRWRRES (getkword
"\nReplace cabinet door with drawers? [Yes/No] <Yes> "
) ;_ end of getkword
) ;_ end of setq
(cond ((= DRWRRES "Yes") (DRAWDRWRS))
((= DRWRRES "No") (ECAB))))



(defun DRAWDRWRS (/ LLCRNR URCRNR PT_LIST DRWRSET DRWRNUM)
(setq LLCRNR (getpoint "\nPick lower left corner of cabinet door: ")
URCRNR (getcorner LLCRNR
"\nPick upper right corner of cabinet door: "
) ;_ end of getcorner
PT_LIST (list URCRNR
(list (car URCRNR) (cadr LLCRNR))
LLCRNR
(list (car LLCRNR) (cadr URCRNR))
) ;_ end of list
DRWRSET (ssget "cp" PT_LIST))
(command "erase" DRWRSET "")
(initget (+ 1 2 4) "2 3")
(setq DRWRNUM (getint "\nSpecify number of additional drawers: [2/3] "))
(cond ((= DRWRNUM "2") (2drwrs))
((= DRWRNUM "3") (3drwrs)))
(princ))


(defun 2DRWRS (/)
(setq TOTDRWRHGT (- DRWRSP 1.5)
DRWRHGT (/ TOTDRWRHGT 2)
DRWR1PT1 LLCRNR
DRWR1PT2 (list (car LLCRNR) (+ (cadr LLCRNR) DRWRHGT))
DRWR1PT3 (list (+ (car LLCRNR) DRWRWDTH) (cadr DRWR1PT2))
DRWR1PT4 (list (car DRWR1PT3) (- (cadr DRWR1PT3) DRWRHGT)))
(command "line" DRWR1PT1 DRWR1PT2 DRWR1PT3 DRWR1PT4 "c")
(princ))

Thanks again for any help you can offer.

RobertB
2005-05-18, 09:47 PM
OK, I'm getting close, I think. This is what I've don to clean up the drawer draw section of the routine. The first "getkword" does not recognize the defualt response of "Yes" when I hit the enter key, but it does recognize "Y" or "N". Also, when it gets to the point of prompting for number of additional drawers it cancels out and takes me back to the command line.

Just flip your logic. When the default is hit, DrwrRes will be nil.
(initget "Yes No")
(setq
DRWRRES (getkword
"\nReplace cabinet door with drawers? [Yes/No] <Yes> "
) ;_ end of getkword
) ;_ end of setq
(cond ((= DRWRRES "No") (ECAB))
(T (DRAWDRWRS))))

Opie
2005-05-18, 09:59 PM
Robert beat me to the punch on the conditional order.

(initget 128 "Yes No") ;<- Place 128 To Allow For Arbitrary Input (User Presses Enter)
(setq
DRWRRES (getkword
"\nReplace cabinet door with drawers? [Yes/No] <Yes> "
) ;_ end of getkword
) ;_ end of setq
(cond ((= DRWRRES "No") (ECAB)) ;<-Reorder Conditional Place The Default Response
(t (DRAWDRWRS)) ; At End To Allow For The Arbitrary Input
)


(defun DRAWDRWRS (/ LLCRNR URCRNR PT_LIST DRWRSET DRWRNUM)
(setq LLCRNR (getpoint "\nPick lower left corner of cabinet door: ")
URCRNR (getcorner LLCRNR
"\nPick upper right corner of cabinet door: "
) ;_ end of getcorner
PT_LIST (list URCRNR
(list (car URCRNR) (cadr LLCRNR))
LLCRNR
(list (car LLCRNR) (cadr URCRNR))
) ;_ end of list
DRWRSET (ssget "cp" PT_LIST)
)
(command "erase" DRWRSET "")
(initget (+ 1 2 4) "2 3")
(setq
DRWRNUM (getint "\nSpecify number of additional drawers: [2/3] ")
)
(DRWRS# DRWRNUM) ;<- Renamed function to allow for number of drawers to be passed as variables
;;; (cond ((= DRWRNUM "2") (2DRWRS)) ;<- conditional not needed see previous line
;;; ((= DRWRNUM "3") (3DRWRS))
;;; )
(princ)
)


(defun DRWRS# ( NUMDRWRS /) ;<- Renamed Function To Allow For Number Of Drawers To Be Sent As A Variable
(setq TOTDRWRHGT (- DRWRSP 1.5) ;<- Not Sure Where This Variable Was Set. Maybe Place Of Crash?
DRWRHGT (/ TOTDRWRHGT NUMDRWRS ) ;<- Placed Number Of Drawers Variable In Place Of 2? (Assumption)
DRWR1PT1 LLCRNR
DRWR1PT2 (list (car LLCRNR) (+ (cadr LLCRNR) DRWRHGT))
DRWR1PT3 (list (+ (car LLCRNR) DRWRWDTH) (cadr DRWR1PT2))
DRWR1PT4 (list (car DRWR1PT3) (- (cadr DRWR1PT3) DRWRHGT))
)
(command "line" DRWR1PT1 DRWR1PT2 DRWR1PT3 DRWR1PT4 "c")
(princ)
)

tflaherty
2005-05-18, 11:05 PM
Allright, I got the first piece to work. THANKS!!

On the second part though it keeps canceling out. I considered the previous suggestion of making the number of drawers a variable to pass on. However, I think doing it that way will give equal size drawers, which is not what I want. If the choice is 2 drawers, yes, they will be equal sizes inside the space with an 1 1/2" space between them. If the choice is 3 drawers, the top drawer will be 4" tall and the other 2 will be equal, again there will be an 1 1/2" space between each drawer. Maybe I haven't constructed my point list correct.

After the command cancels out I check the value of my variables at the command line and they all say nil. Is that what it's suppose to do since the command ended?


(defun 2DRWRS (/)
(setq DRWRSP (distance LLCRNR ULCRNR)
TOTDRWRHGT (- DRWRSP 1.5)
DRWRHGT (/ TOTDRWRHGT 2)
DRWR1PT1 LLCRNR
DRWR1PT2 (list (car LLCRNR) (+ (cadr LLCRNR) DRWRHGT))
DRWR1PT3 (list (+ (car LLCRNR) DRWRWDTH) (cadr DRWR1PT2))
DRWR1PT4 (list (car DRWR1PT3) (- (cadr DRWR1PT3) DRWRHGT)))
(command "line" DRWR1PT1 DRWR1PT2 DRWR1PT3 DRWR1PT4 "c")
(princ))


(initget "Yes No")
(setq
DRWRRES (getkword
"\nReplace cabinet door with drawers? [Yes/No] <Yes> "
) ;_ end of getkword
) ;_ end of setq
(cond ((= DRWRRES "No") (ECAB))
(T (DRAWDRWRS))))



(defun DRAWDRWRS (/ LLCRNR URCRNR PT_LIST DRWRSET DRWRNUM)
(setq LLCRNR (getpoint "\nPick lower left corner of cabinet door: ")
URCRNR (getcorner LLCRNR
"\nPick upper right corner of cabinet door: "
) ;_ end of getcorner
PT_LIST (list URCRNR
(list (car URCRNR) (cadr LLCRNR))
LLCRNR
(list (car LLCRNR) (cadr URCRNR))
) ;_ end of list
DRWRSET (ssget "cp" PT_LIST)
ULCRNR (list (car LLCRNR) (cadr URCRNR))
LRCRNR (list (car URCRNR) (cadr LLCRNR)))
(command "erase" DRWRSET "")
(initget "2 3")
(setq DRWRNUM (getint "\nSpecify number of additional drawers: [2/3] "))
(cond ((= DRWRNUM "2") (2DRWRS))
((= DRWRNUM "3") (3DRWRS)))
(princ))

Opie
2005-05-18, 11:14 PM
On the second part though it keeps canceling out. I considered the previous suggestion of making the number of drawers a variable to pass on. However, I think doing it that way will give equal size drawers, which is not what I want. If the choice is 2 drawers, yes, they will be equal sizes inside the space with an 1 1/2" space between them. If the choice is 3 drawers, the top drawer will be 4" tall and the other 2 will be equal, again there will be an 1 1/2" space between each drawer. Maybe I haven't constructed my point list correct.
Do you use the internal vlisp editor provided with acad? If so, you can set a break point in your code and run through your code one line at a time to see where your function is crashing.
After the command cancels out I check the value of my variables at the command line and they all say nil. Is that what it's suppose to do since the command ended?

The variable behind the / are considered local variables. once the command quits, those variable are reset to nil automatically. To not define them as local, you would need to remove them past the / in your (defun drawdrwrs ( / )

(defun DRAWDRWRS (/ LLCRNR URCRNR PT_LIST DRWRSET DRWRNUM)

tflaherty
2005-05-19, 12:03 AM
I do use the vlide in AutoCAD. However, I'm not familiar with you to use the break function to debug.

tflaherty
2005-05-19, 12:34 AM
Ok, I've found the problem, just don't know how to fix it or why it's happening. I traced the values of LLCRNR, URCRNR, ULCRNR and LRCRNR. At the point where it cancels out LLCRNR and URCRNR evaluate to nil (odd because they are the points the user picks) but, ULCRNR and LRCRNR do have values which the program constructed from the 2 previous points the user picked. I don't understand how or where the variables are being set to nil.



(defun DRAWDRWRS (/ LLCRNR URCRNR PT_LIST DRWRSET DRWRNUM)
(setq LLCRNR (getpoint "\nPick lower left corner of cabinet door: ")
URCRNR (getcorner LLCRNR
"\nPick upper right corner of cabinet door: "
)
ULCRNR (list (car LLCRNR) (cadr URCRNR))
LRCRNR (list (car URCRNR) (cadr LLCRNR))
PT_LIST (list LLCRNR ULCRNR URCRNR LRCRNR) ;_ end of list
DRWRSET (ssget "cp" pt_list))
(command "erase" DRWRSET "")
(initget "2 3")
(setq DRWRNUM (getint "\nSpecify number of additional drawers: [2/3] "))
(if (= DRWRNUM "2")
(progn
(setq DRWRSP (distance LLCRNR ULCRNR)
TOTDRWRHGT (- DRWRSP 1.5)
DRWRHGT (/ TOTDRWRHGT 2)
DRWRWDTH (distance LLCRNR LRCRNR)
DRWR1PT1 LLCRNR
DRWR1PT2 (list (car LLCRNR) (+ (cadr LLCRNR) DRWRHGT))
DRWR1PT3 (list (+ (car LLCRNR) DRWRWDTH) (cadr DRWR1PT2))
DRWR1PT4 (list (car DRWR1PT3) (- (cadr DRWR1PT3) DRWRHGT)))
(command "erase" DRWRSET "")
(command "line" DRWR1PT1 DRWR1PT2 pause)
(command "line" drwr1pt2 DRWR1PT3 pause)
(command "line" drwr1pt3 DRWR1PT4 pause)
(command "line" drwr1pt4 drwr1pt1 pause "")
(princ))))

Opie
2005-05-19, 12:59 AM
Here you are requesting an integer.
(setq DRWRNUM (getint "\nSpecify number of additional drawers: [2/3] "))
but the next line you are testing for a string.
(if (= DRWRNUM "2")
remove the quotes from around the 2 this will allow you to get past the conditional statement and into your remaining code.

The following is a line that is not necessary, since your have already deleted the information once before.
(command "erase" DRWRSET "")

I cannot decipher your PAUSEs in your line commands
(command "line" DRWR1PT1 DRWR1PT2 pause)
(command "line" drwr1pt2 DRWR1PT3 pause)
(command "line" drwr1pt3 DRWR1PT4 pause)
(command "line" drwr1pt4 drwr1pt1 pause "")
You could incorporate all of those line commands into one command line.
(command "line" DRWR1PT1 DRWR1PT2 DRWR1PT2 DRWR1PT3 DRWR1PT3 DRWR1PT4 DRWR1PT4 DRWR1PT1 "")
HTH