Help with GRREAD

Hello:

I have written a little lisp routine that draws a door way, I would like to use GRREAD to allow the user to choose the open angle of the door and draw an arc representing the sweep of the door.  I have the lisp setup and the program draws the door and the arc using a hard coded angle.  I have googled GRREAD and arrived at a huge forum thread at www.theswamp.org but I could not figure out how to make use of the expression, I noticed a lot of examples, but very few of them were commented so I was at a loss to learn anything from them.  Anyway, I was wondering if somebody would be able to help me to create a little routine to use GRREAD to rotate the door.  I can post the code that I already have written as a starting point.

From what I could gather, I draw my rectangle on the screen and somehow use a while loop to ask the user to select an angle, depending upon the input the user provides the while loop will end, so I am thinking that the while loop should be controlled by the result of the GRREAD expression, the content of the while loop, rotates my box and draws the arc based on the current cursor coordinates.  But this doesn't add up to me, should I be erasing the arc each time the cursor is moved?

Thanks! 

Comments

  • I assume that you want the user to click a point using a know point as a reference. In the code below the known point is hard-coded (ptMain).
    [code](defun Test ( / grResult ptMain ptUser)
      (setq ptMain '(0.0 0.0 0.0))
      (while (and (setq grResult (grread T)) (= (car grResult) 5))
        (redraw) ; Remove temp graphics.
        (setq ptUser (cadr grResult))
        (grvecs (list 256 ptMain ptUser)) ; Create temp graphics.
      )
      (redraw) ; Remove temp graphics.
      ptUser
    )[/code]
  • Hmmm, Something seems to be wrong with the display of the code in my previous post. My guess is a CSS issue. You can however select the code and paste it in a text editor.

    Another test below:
    [code]Test 1 2 3[/code]
  • Looks like they have applied the invisible ink CSS. They want to make LISP more appear more mysterious than it already is. :-)

    Something to be aware of with GRREAD is that you can't use object snaps. If this is important to you for your particular example you could instead use GETANGLE providing the hinge point of the door as the base point. You will get the same rubber banding effect, be able to use osnap, or simply type in an angle.

    [code](setq ang (getangle '(12.0 5.0) "Door Angle: "))[/code]

    Regards,

    Jason Bourhill

    CAD Concepts 


  • Interesting!  Snaps aren't needed in this scenario, I tried to get something to work, I did a bit of coding and tried to modify a yinyang example I found on the swamp but it's just freezing up BricsCAD.

    I think GRREAD is the proper tool to use here, I am drawing the door by defining a couple of points using the polar expression, the arc then uses one of the points defined by the angle of the door as its end point, so if the user is dynamically choosing the door angle, the end point of the arc will change.  I could just do this by asking for an angle but I've wanted to try to build GRREAD into an application for ages.

    Incidentally, there is a typo in the CSS file that is causing the lacking display of the code, I'll send a support request about it.
  •  I spent a bit more time banging away on the keyboard and came up with the following: 

    [code](defun c:door ()
      ;Original by Scott McKenzie - use as you please, just don't sell it in whole or part and please give credit

      ;Get a few variables from the user
      
      (setq OpeningWidth (getdist "\nENTER DOOR WIDTH: "))
      (setq OpeningHeight (getdist "\nENTER DOOR HEIGHT: "))
      (setq WallThickness (getdist "\nENTER WALL THICKNESS: "))
      (setq InsPoint (getpoint "\nSELECT INSERTION POINT: "))
        
      ;Set a few preset dimensions
      
      (setq DoorThk 1.00)
      (setq DoorAngle 45.00)
      (setq JambThickenss 0.50)
      (setq StopThickness 0.50)
      
      ;Define a selection set
      
      (setq DoorsSS (ssadd))
      (setq DoorsTrimSS (ssadd))
      
      ;Record the OSmode
      
      (setq Doors_POSMode (getvar "osmode"))
      (setvar "osmode" 0)
      
      ;Define the left jamb points
      
      (setq p1 (polar InsPoint (* pi 1) (/ OpeningWidth 2)))
      (setq p2 (polar p1 (/ pi 2) WallThickness))
      (setq p3 (polar p2 (* pi 1) JambThickenss))
      (setq p4 (polar p3  (* pi 1.5) WallThickness))
      
      ;Define the left stop points
        
      (setq p5 (polar p1 0 StopThickness))
      (setq p6 (polar p5 (* pi 0.5) (- WallThickness DoorThk)))
      (setq p7 (polar p6 (* pi 1) StopThickness))
      
      ;Draw the left jamb and stop, adding to the selection set as we go
       
      (command ".pline" p1 p2 p3 "")
      (ssadd (entlast) DoorsSS)
        
      (command ".line" p3 p4 "") ;<-- This is the left trim line </div>
      (ssadd (entlast) DoorsSS)
      (ssadd (entlast) DoorsTrimSS)
      
      (command ".pline" p4 p5 p6 p7 "")
      (ssadd (entlast) DoorsSS)
      
      ;Define the right jamb points
        
      (setq p8 (polar InsPoint 0 (/ OpeningWidth 2)))
      (setq p9 (polar p8 (/ pi 2) WallThickness))
      (setq p10 (polar p9 0 JambThickenss))
      (setq p11 (polar p10 (* pi 1.5) WallThickness))
      
      ;Define the right stop points
          
      (setq p12 (polar p8 (* pi 1) StopThickness))
      (setq p13 (polar p12 (* pi 0.5) (- WallThickness DoorThk)))
      (setq p14 (polar p13 0 StopThickness))
      
      (command ".pline" p8 p9 p10 "")
      (ssadd (entlast) DoorsSS)
      
      (command ".line" p10 p11 "") ;This is the right trim line
      (ssadd (entlast) DoorsSS)
      (ssadd (entlast) DoorsTrimSS)
      
      (command ".pline" p11 p12 p13 p14 "")
      (ssadd (entlast) DoorsSS)
      
      ;Determine the layer for the arc
      
      (cond
        ((= (getvar "clayer") "OBJECT")
          (setq ArcLayer "HIDDEN")
          (setq ArcLT "Dashed")
        )
        ((= (getvar "clayer") "EXIST")
          (setq ArcLayer "EXIST-LT")
          (setq ArcLT "Dashed")
        )
        (t 
          (set ArcLT (getvar "celtype"))
          (setq ArcLayer (getvar "clayer"))    
        )  
      )
      
      ;Set the loop flag, we want to start looping
      
      (setq loop T)
      
      ;The loop, we will draw the objects as the user moves around
      
      (while (and (= Loop T) (setq MouseInput (grread T 12 0)))
        (cond
          ((= (car MouseInput) 5)
            
            ;Delete the arc and rectangle
            
            (if (/= nil Rectangle)
              (progn
                (entdel Rectangle)
                (setq Rectangle nil)
              )
            )
            (if (/= nil Arc)
     (progn
       (entdel Arc)
       (setq Arc nil)
     )
            )
           
            ;Get the coordinates of the mouse
            
            (setq MousePoint (cadr MouseInput))
            
            ;Calculate the points of the door.
            
            (setq p15 (polar p2 (angle MousePoint p2) OpeningWidth))
            (setq p16 (polar p15 (- (angle MousePoint p2) (/ pi 2)) DoorThk))
            (setq P17 (polar p16 (+ (angle MousePoint p2) pi) OpeningWidth))
      
            ;Draw the door
      
            (setq Rectangle
              (entmakex 
                (list 
                  '(0 . "LWPOLYLINE")
                  '(100 . "AcDbEntity")
                  '(100 . "AcDbPolyline")
                  '(70 . 0)
                  '(90 . 5)
                  (cons 10 p2)
                  '(40 . 0.0)
                  '(41 . 0.0)
                  '(42 . 0.0) 
                  (cons 10 p15)
                  '(40 . 0.0)
                  '(41 . 0.0)
                  '(42 . 0.0)
                  (cons 10 p16)
                  '(40 . 0.0)'
                  '(41 . 0.0)'
                  '(42 . 0.0) 
                  (cons 10 p17)
                  '(40 . 0.0)
                  '(41 . 0.0)'
                  '(42 . 0.0) 
                  (cons 10 p2)
                )
              )
            )
            
            ;Draw the arc
            
            (setq Arc
              (entmakex
                (list 
                  '(0 . "ARC")
                  '(100 . "AcDbEntity") 
                  '(67 . 0)
                  '(8 . "OBJECT")
                  '(100 . "AcDbCircle")
                  (cons 8 ArcLayer)
                  (cons 6 ArcLT)
                  (cons 10 p2)
                  (cons 40 OpeningWidth)
                  '(210 0.0 0.0 1.0)
                  '(100 . "AcDbArc")
                  '(50 . 0.0)
                  (cons 51 (angle MousePoint p2))
                )
              )
            )
          )
          ((= (car MouseInput) 3)
            ;Cancel the loop if the user did something?
            (setq loop nil)
          )
          (T 
            ;If the user did anything but click, just delete the rectangle and arc and cancel the loop
            (and Rectangle (entdel Rectangle) (setq Rectangle nil))
            (and Arc (entdel Arc) (setq Arc nil)) 
            (setq loop nil)
          )
        ) 
      )
      
      ;Rotate the door into position
      
      (command ".rotate" DoorsSS "" InsPoint "r" p1 p8 pause)|;
      
      ;Reset osmode and layers
      
      ;(setvar "celtype" Doors_PCELType)
      ;(setvar "clayer" Doors_PLayer)
      ;(setvar "osmode" Doors_POSMode)
      
      (princ)
    )[/code]

    It's not perfect, but it does draw my door and my arc, albeit the mouse cursor is 180 degrees from where it should be.  And now I have to figure out how to add the arc and rectangle representing the door to a selection set so that I can rotate the whole assembly into place.  This isn't the best method, I should use another GRREAD to have user select the rotation of the door, and then do a second GRREAD to place the door and arc.  But it's a start and maybe somebody else can get some use out of it.
  • Not sure what happened with the formatting, but here it is outside of the code tags

    (defun c:door ()

      ;Original by Scott McKenzie - use as you please, just don't sell it in whole or part and please give credit

      ;Get a few variables from the user
      
      (setq OpeningWidth (getdist "\nENTER DOOR WIDTH: "))
      (setq OpeningHeight (getdist "\nENTER DOOR HEIGHT: "))
      (setq WallThickness (getdist "\nENTER WALL THICKNESS: "))
      (setq InsPoint (getpoint "\nSELECT INSERTION POINT: "))
        
      ;Set a few preset dimensions
      
      (setq DoorThk 1.00)
      (setq DoorAngle 45.00)
      (setq JambThickenss 0.50)
      (setq StopThickness 0.50)
      
      ;Define a selection set
      
      (setq DoorsSS (ssadd))
      (setq DoorsTrimSS (ssadd))
      
      ;Record the OSmode
      
      (setq Doors_POSMode (getvar "osmode"))
      (setvar "osmode" 0)
      
      ;Define the left jamb points
      
      (setq p1 (polar InsPoint (* pi 1) (/ OpeningWidth 2)))
      (setq p2 (polar p1 (/ pi 2) WallThickness))
      (setq p3 (polar p2 (* pi 1) JambThickenss))
      (setq p4 (polar p3  (* pi 1.5) WallThickness))
      
      ;Define the left stop points
        
      (setq p5 (polar p1 0 StopThickness))
      (setq p6 (polar p5 (* pi 0.5) (- WallThickness DoorThk)))
      (setq p7 (polar p6 (* pi 1) StopThickness))
      
      ;Draw the left jamb and stop, adding to the selection set as we go
       
      (command ".pline" p1 p2 p3 "")
      (ssadd (entlast) DoorsSS)
        
      (command ".line" p3 p4 "") ;<-- This is the left trim line</div>
      (ssadd (entlast) DoorsSS)
      (ssadd (entlast) DoorsTrimSS)
      
      (command ".pline" p4 p5 p6 p7 "")
      (ssadd (entlast) DoorsSS)
      
      ;Define the right jamb points
        
      (setq p8 (polar InsPoint 0 (/ OpeningWidth 2)))
      (setq p9 (polar p8 (/ pi 2) WallThickness))
      (setq p10 (polar p9 0 JambThickenss))
      (setq p11 (polar p10 (* pi 1.5) WallThickness))
      
      ;Define the right stop points
          
      (setq p12 (polar p8 (* pi 1) StopThickness))
      (setq p13 (polar p12 (* pi 0.5) (- WallThickness DoorThk)))
      (setq p14 (polar p13 0 StopThickness))
      
      (command ".pline" p8 p9 p10 "")
      (ssadd (entlast) DoorsSS)
      
      (command ".line" p10 p11 "") ;This is the right trim line
      (ssadd (entlast) DoorsSS)
      (ssadd (entlast) DoorsTrimSS)
      
      (command ".pline" p11 p12 p13 p14 "")
      (ssadd (entlast) DoorsSS)
      
      ;Determine the layer for the arc
      
      (cond
        ((= (getvar "clayer") "OBJECT")
          (setq ArcLayer "HIDDEN")
          (setq ArcLT "Dashed")
        )
        ((= (getvar "clayer") "EXIST")
          (setq ArcLayer "EXIST-LT")
          (setq ArcLT "Dashed")
        )
        (t 
          (set ArcLT (getvar "celtype"))
          (setq ArcLayer (getvar "clayer"))    
        )  
      )
      
      ;Set the loop flag, we want to start looping
      
      (setq loop T)
      
      ;The loop, we will draw the objects as the user moves around
      
      (while (and (= Loop T) (setq MouseInput (grread T 12 0)))
        (cond
          ((= (car MouseInput) 5)
            
            ;Delete the arc and rectangle
            
            (if (/= nil Rectangle)
              (progn
                (entdel Rectangle)
                (setq Rectangle nil)
              )
            )
            (if (/= nil Arc)
     (progn
       (entdel Arc)
       (setq Arc nil)
     )
            )
           
            ;Get the coordinates of the mouse
            
            (setq MousePoint (cadr MouseInput))
            
            ;Calculate the points of the door.
            
            (setq p15 (polar p2 (angle MousePoint p2) OpeningWidth))
            (setq p16 (polar p15 (- (angle MousePoint p2) (/ pi 2)) DoorThk))
            (setq P17 (polar p16 (+ (angle MousePoint p2) pi) OpeningWidth))
      
            ;Draw the door
      
            (setq Rectangle
              (entmakex 
                (list 
                  '(0 . "LWPOLYLINE")
                  '(100 . "AcDbEntity")
                  '(100 . "AcDbPolyline")
                  '(70 . 0)
                  '(90 . 5)
                  (cons 10 p2)
                  '(40 . 0.0)
                  '(41 . 0.0)
                  '(42 . 0.0) 
                  (cons 10 p15)
                  '(40 . 0.0)
                  '(41 . 0.0)
                  '(42 . 0.0)
                  (cons 10 p16)
                  '(40 . 0.0)'
                  '(41 . 0.0)'
                  '(42 . 0.0) 
                  (cons 10 p17)
                  '(40 . 0.0)
                  '(41 . 0.0)'
                  '(42 . 0.0) 
                  (cons 10 p2)
                )
              )
            )
            
            ;Draw the arc
            
            (setq Arc
              (entmakex
                (list 
                  '(0 . "ARC")
                  '(100 . "AcDbEntity") 
                  '(67 . 0)
                  '(8 . "OBJECT")
                  '(100 . "AcDbCircle")
                  (cons 8 ArcLayer)
                  (cons 6 ArcLT)
                  (cons 10 p2)
                  (cons 40 OpeningWidth)
                  '(210 0.0 0.0 1.0)
                  '(100 . "AcDbArc")
                  '(50 . 0.0)
                  (cons 51 (angle MousePoint p2))
                )
              )
            )
          )
          ((= (car MouseInput) 3)
            ;Cancel the loop if the user did something?
            (setq loop nil)
          )
          (T 
            ;If the user did anything but click, just delete the rectangle and arc and cancel the loop
            (and Rectangle (entdel Rectangle) (setq Rectangle nil))
            (and Arc (entdel Arc) (setq Arc nil)) 
            (setq loop nil)
          )
        ) 
      )
      
      ;Rotate the door into position
      
      (command ".rotate" DoorsSS "" InsPoint "r" p1 p8 pause)|;
      
      ;Reset osmode and layers
      
      ;(setvar "celtype" Doors_PCELType)
      ;(setvar "clayer" Doors_PLayer)
      ;(setvar "osmode" Doors_POSMode)
      
      (princ)
    )
  • Scott it seems you know how to work with grread. Very good!
    Two tips:
    1. Localize your variables.
    2. You have a (set ...) where you probably need to use (setq ...).
  •  Thanks for the tips Roy, I am surprised that the routine didn't crash, but maybe that portion of the code didn't execute, I will fix it up.  Ahh yes, localizing variables, I noticed that without localizing the Arc and Rectangle variables that if you run the command twice in a row, the first drawn arc and rectangle are removed and redrawn.  When I have some time to tweak this a bit more I will repost it here...
This discussion has been closed.