Jump to content

AutoLISP Beginner - automatic offset idea based on nearby plines


highrise_uk

Recommended Posts

Hi all, 

 

Been reading the forums for ages, but finally have a thing I'd like some help figuring out. 

 

I mostly use CAD to do town planning parking work. Our company has a design style whereby we fill all the proposed parking bays with a certain colour polyline. 

 

I made my first working LISP last week, which allows you to select the long line of the bay, then choose which side to make an offset line. Then it makes it the right thickness and also the right layer, and moves it to back, and then repeats so you can do many in quick sucessions:

 

See pics for example: 

 

image.thumb.png.9af22c4ece44eddb81574edfaabd6d23.png

 

image.thumb.png.4b792b7f24960e047e2803dfcd6028db.png

 

This is cool and enables me to do this for all the bays relatively quickly. 

 

But, knowing how good LISPs can be, I was wondering if there was a way of automating it to do this for every single bay in the drawing. 

 

Here's the current LISP: 

 

(defun C:PBH ()
  (repeat 1000
  (command "pselect" pause "") ;select line
  (command "offset" "e" "n" "1" pause "") ;select offset side
  (command "pselect" "l" "") ;auto-select previous item
  (setq ss (ssget "I")) ;set item to ss 
  (command "_.chprop" ss "" "LT" "Bylayer" "LA" "PR-HATCH-PARKING BAY-RESIDENT PERMIT ONLY" "") ;set item to layer
  (command "_pedit" ss "W" "2" "") ;set item to 2m width
  (command "pselect" "l" "") ;auto-select last item
  (command "draworder" "b" "" "") ;send item to back
    )
  (princ)
  )

 

I was thinking, if there was a way for the program to find all lines on the parking bay layer longer than 2m (to make it ignore the short ones at each end), and then automatically work out which side those short lines are so that it knows what side to make the fill line, and do this for every item. 

 

Is there a get command or something which would assess which direction those short lines were facing, (they are touching the long line), and then run that command on everything. 

 

Been really enjoying gradually learning how these work, I'm assuming this would make it a lot more complicated but I'm keen to experiment if it's possible. 

 

Cheers

 

 

Edited by highrise_uk
Link to comment
Share on other sites

Well done, onto a slippery slope though "I wonder if I can make a LISP that can do....."

 

We might need a sample of a drawing to check and confirm how you draw things. 

 

I'll take a guess that the parking bay lines are unique in some way, perhaps on their own layer, so to set you off you might use ssget with a filter for the layer

 

(setq ParkingLines (ssget (list (cons 8 Parking-Lines-Layer))) )

 

and if you use (ssget "_X" ... ) it will select everything else you select in the first example ( see https://lee-mac.com/ssget.html - Lee Mac has a lot of excellent resources, same as this website, AfraLisp and The Swamp)

 

In your code you can then ditch the (repeat 1000) (by the way there are better ways but this can work) and use a while loop perhaps:

 

(setq acount 0)
(while (< acount (sslength ParkingLines))

... do stuff              
                
  (setq MyLine (ssname ParkingLines acount))
  (command "_.chprop" MyLine "" "LT" "Bylayer" "LA" "PR-HATCH-PARKING BAY-RESIDENT PERMIT ONLY" "") ;set item to layer

....
                
  (setq acount (+ acount 1))
) ; end while

 

 

 

If it was me I'd perhaps create a selection set of the parking bay lines and loop through that set (as above), zoom to and highlighting each polyline in turn (use redraw -entity name- 3 to highlight, 4 to remove highlight), user can select side, draw the hatch and move on.

 

If the parking bay line is always [ shaped and a polyline you could automate the offset side by using the 1st point in the polyline definition as the offset selection.

 

 

If I remember after the weekend this might be an interesting on to look at

  • Like 1
Link to comment
Share on other sites

Welcome to the forums. ssget is what your looking for. you can use that to filter by entity type, layer, color basically anything in the DXF code. so all you really have to do is drag a window around everything to make one selection.

This will dump the dxf codes of a selected entity to the command line

;;----------------------------------------------------------------------------;;
;; Dump all DXF Group Data             
(defun C:DumpIt (/ ent)
  (while (setq ent (car (entsel "\nSelect Entity to Dump")))
    (mapcar 'print (entget ent '( "*")))
  )
  (princ)
)

 

Lee Mac has a great website going over all the ssget options

this will only select lines on "parking line" Layer  - (setq ss (ssget '((0 . "LINE") (8 . "PARKING LINE"))))

from there you can use the end points to calculate the distance of said lines to filter down to the "long ones"


Took a little time to add a few QOL to your code.

 

(defun c:foo (/ s d p LastEnt SS en)
  ;; Tharwat 14. Dec. 2011 ;; Modified by Mhupp
  (setq SS (ssadd)) ;A blank selection set is need to add things to later
  (while (setq s (car (entsel "\nSelect entity: "))) ;keeps repeating the command if you keep selecting things
    (if (not (member (cdr (assoc 0 (entget s))) '("*LINE" "CIRCLE" "ARC" "ELLIPSE"))) ;checks to see if the selection is a type of entity in the list
      (progn                                                                          ;remove any if you want the command to prompt you to select again
        (prompt "\nCan't Offset Selected Object, Try again")
        (c:foo)  ; Call the command again for retry (recursion) if you rename this command rename it here to.
      )
      (progn
        (if (setq d (getdist "\nDistance of offset <1>: ")) ;getdist allows you to key in things like 12'6" or use your mouse.
		  (progn)               ;if d is set do nothing
		  (setq dist 1)         ;Else if the user presses Enter, set d to 1
		)			
        (setq p (getpoint "\nSpecify Offset Side: "))
        ;; Store the last entity created before the offset, Offset can create multiple entitys
        (setq LastEnt (entlast))
        (command "_.offset" d s p "")
        ;; Add all newly created entities to the selection set
        (while (setq en (entnext LastEnt))
          (ssadd en SS)
        )
        ;; Process the newly created Selection set
        (foreach ent (vl-remove-if 'listp (mapcar 'cadr (ssnamex SS))) ;this will create a list of entity name in selection set SS
          (setq vlaEnt (vlax-ename->vla-object ent)) ;gets the visual list name of an entity
		  ;; Set color to "ByLayer"
          (vla-put-color vlaEnt acByLayer)
          ;; Set to the layer "PR-HATCH-PARKING BAY-RESIDENT PERMIT ONLY"
          (vla-put-layer vlaEnt "PR-HATCH-PARKING BAY-RESIDENT PERMIT ONLY")
          ;; Set width to 2
		  (vla-put-ConstantWidth vlaEnt 2.0) ;always good pratice to use real numbers and not integer
          (command "_.draworder" ent "back") 
        )
      )
    )
  )
  (princ)
)

 

Modified from here

Edited by mhupp
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...