AutoLISP to offset closed polyline, hatch, and delete the second polyline [C3D]

AutoLISP to offset closed polyline, hatch, and delete the second polyline [C3D]

Anonymous
Not applicable
13,510 Views
106 Replies
Message 1 of 107

AutoLISP to offset closed polyline, hatch, and delete the second polyline [C3D]

Anonymous
Not applicable

Hi. In our firm, we often created partial hatches within buildings (represented by closed polylines). The process is as follows:
1. We select a closed polyline that was previously drawn and that represents the outline of a building.

2. We offset the polyline 2 units inside, creating a scaled version of the original polyline within the first. 

3. We hatch the area within the two polylines with a specific hatch pattern, scale, layer and color.

4. We delete the smaller, inside polyline, leaving the original building outline and the new hatch within.

I'm looking to automate this process in some way. I had some marginal success with the Action Recorder, but it wasn't consistent if the building outline was angled, and I had to always use the rightmost edge of the building. I'm sure AutoLISP can automate this sequence, but I'm a complete beginner.

Can anybody spoonfeed me a script that does what I'm looking for? Thanks a whole ton.

13,511 Views
106 Replies
Replies (106)
Message 61 of 107

Kent1Cooper
Consultant
Consultant

That should be possible, but which of my earlier Messages here has the code you are using?  Also, in the context of this topic, would you be using only the inward-offsetting command from OffsetInOrOut, or is the idea just to steal its multiple-selection capability and work that part into something from here?

Kent Cooper, AIA
Message 62 of 107

MauCabrera789
Enthusiast
Enthusiast

I was referring to this reply of yours (message 35 in this thread).

 

In the context of this topic, the core idea was to incorporate multiple-selection capability into your offset-hatching program OI2H.lsp, because at the moment it only accepts a single input.

 

I brought up OffsetInOrOut.lsp because, from my understanding, you already took care of a lot of the heavy lifting with regards to defining a function that can offset a lot of polylines simultaneously. I just thought some of the concepts could potentially be useful to incorporate into OI2H.lsp to bring on multiple-selection capability. Maybe OffsetInOrOut.lsp could even be directly referenced to as a function within OI2H.lsp. I'm not a .lisp wizard or anything remotely close, just throwing some ideas out that may help to inspire a direction!

0 Likes
Message 63 of 107

john.uhden
Mentor
Mentor

@MauCabrera789 

The problem that many run into is that offsetting is not really inward or outward.  It's actually to the left or to the right.  Unless you know in advance which way a polyline is directed, you don't know which way is left or which way is right.  That's why many programmers, including Autodesk itself, want you to pick the offset side of each polyline, the keyword being "each."  The software then figures out if the point picked is to the left or to the right.  So I can't figure out what rule could be applied to offset a number of polylines in one swell foop, unless the choice is either inward or outward depending on each polyline's general direction, being CW or CCW.  But a polyline with only two vertices is neither CW nor CCW.

If you could establish a foolproof rule, then we might be able to help you avoid one at a time.

John F. Uhden

Message 64 of 107

Kent1Cooper
Consultant
Consultant

 


@MauCabrera789 wrote:

....

In the context of this topic, the core idea was to incorporate multiple-selection capability into your offset-hatching program OI2H.lsp, because at the moment it only accepts a single input.

 

I brought up OffsetInOrOut.lsp because, from my understanding, you already took care of a lot of the heavy lifting with regards to defining a function that can offset a lot of polylines simultaneously. ....


Not so heavy lifting, really....  Just a matter of a selection set rather than a single object, and a (repeat) function to step through that set and do the same to each object in it.  Minimally tested:

 

(defun C:OI2H ; = Offset Inward by 2 drawing units, and Hatch
  (/ *error* doc ss n ent obj oarea pickpt pl2)
  (defun *error* (errmsg)
    (if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break"))
      (princ (strcat "\nError: " errmsg))
    ); if
    (vla-endundomark doc)
    (princ)
  ); defun - *error*
  (vla-startundomark (setq doc (vla-get-activedocument (vlax-get-acad-object))))
  (prompt "\nBuilding outline to Offset Inward and Hatch: ")
  (if (setq ss (ssget "_:L" '((0 . "LWPOLYLINE") (-4 . "&") (70 . 1)))); on unlocked Layers, closed
    (repeat (setq n (sslength ss)); then
      (setq
        obj (vlax-ename->vla-object (setq ent (ssname ss (setq n (1- n)))))
        oarea (vla-get-Area obj)
        pickpt (vlax-curve-getClosestPointTo obj (last (last (last (ssnamex ss)))))
      ); setq
      (vla-offset obj 2)
      (if (> (vla-get-Area (vlax-ename->vla-object (entlast))) oarea)
        (progn ; then -- went wrong way
          (entdel (entlast))
          (vla-offset obj -2)
        ); progn
      ); if [went wrong way -- no else; do nothing if it went right way]
      (command
        "_.hatch" "USER"
          (cvunit
            (+ 
              (angle '(0 0 0) (vlax-curve-getFirstDeriv obj (vlax-curve-getParamAtPoint obj pickpt)))
              (/ pi 4)
            ); +
            "radian" "degree"
          ); cvunit
          0.75 "_no" ent (setq pl2 (entlast)) "" "" ; <-- EDIT 0.75 as preferred
        "_.chprop" "_last" "" "_layer" "YourLayerName" "" ; <-- EDIT Layer name
        "_.erase" pl2 ""
      )
    ); repeat -- then
  ); if
  (vla-endundomark doc)
  (princ)
); defun -- C:OI2H
(vl-load-com)
(prompt "\nType OI2H to Offset Inward by 2 drawing units and Hatch.")

 

Don't listen to curmudgeonly John about in/out vs. left/right.  In the context of this topic [building footprints], the area comparison works fine, but do listen to other earlier caveats that apply whether comparing areas or determining drawn direction.  The too-small-to-Offset-inward issue from the OffsetInOrOut topic is probably not a concern unless you have garden sheds or something tiny like that.  But the possibility that something is of a convoluted-enough shape that more than one object results from Offsetting it is something to be aware of.

Kent Cooper, AIA
Message 65 of 107

MauCabrera789
Enthusiast
Enthusiast

Thank you! Highly appreciate your swift help with this.

 

I figured John brought up some solid points, but your offsetting program is doing the trick just fine for a large set of closed polylines. I'll keep an eye out for the caveats.

0 Likes
Message 66 of 107

john.uhden
Mentor
Mentor

@MauCabrera789 ,

@Kent1Cooper is a very very clever guy.

If there's a solution to be found, he will most likely find it.  I think we all look up to him.

I guess you could call me somewhat particular.  I want my hatching at 45° to the sides and I want to hatch polylines that aren't closed.  The survey crew locates adjacent house corners looking from within the PIQ and the street.  The shape of the other side of the neighbor's house is immaterial.

John F. Uhden

0 Likes
Message 67 of 107

kmohs
Contributor
Contributor
If I set the value of an offset distance based on "cannoscalevalue" for setq (vla-offset obj...), how would I go about setting the negative value?
0 Likes
Message 68 of 107

Kent1Cooper
Consultant
Consultant

@kmohs wrote:
If I set the value of an offset distance based on "cannoscalevalue" for setq (vla-offset obj...), how would I go about setting the negative value?

A (-) function with only one argument gives you the negative of that argument:

(vla-offset obj (- YourValueOrVariable))

 

Kent Cooper, AIA
Message 69 of 107

saqib_tipa
Advocate
Advocate

Hello @john.uhden 

This is very nice Lisp. Can you please make this lisp to work only vertical direction. Like we copy a line vertically (upside or downside) at a distance then we close it's both end and hatch it. 

Thank you.

0 Likes
Message 70 of 107

john.uhden
Mentor
Mentor

@saqib_tipa ,

I don't think I understand your request.  Do you want the hatch to always be vertical?

Do you use twisted views?

Anyway, if you are building closed polylines, then you should need nothing more than the HATCH command.

John F. Uhden

0 Likes
Message 71 of 107

saqib_tipa
Advocate
Advocate

@john.uhden

 

Thank you for reply. I don't use twisted view it will always be world UCS. 

Let me explain, If you have a polyline with several vertices and it's not straight line but zigzag type and you give offset then every vertex will be perpendicular to original vertex. But if we copy first Polyline vertically (ortho mode on) to some distance then every vertex will be copied at same vertical location (plz see image). I need this type of hatch instead of offset it should copy vertically and close end points and apply hatch.

Hope you understand.

Thank you.

 
 

 

 

0 Likes
Message 72 of 107

john.uhden
Mentor
Mentor

@saqib_tipa ,

Ahah.  I see what you would like, but copying does not offset the vertical sides inward.

In the image below, the white is the original, the red is the offset or copy, and the green is obviously the hatch.

johnuhden_0-1720807279517.png (I retained the red offset here just for display purposes.)

I'm sure I could figure out a way to "offset" the sides inward, but there doesn't seem to be much visual difference between the horizontal points via copying vs. offsetting.  I mean the red offset/copy won't be used for any data calculations, will it?  In fact it will be deleted, right?

 

John F. Uhden

0 Likes
Message 73 of 107

saqib_tipa
Advocate
Advocate

@john.uhden 

Thank you for the reply. In my case there will be no vertical lines on both sides but a horizintal (zig zag) Polyline with several vertices which have different Y axis values.

I want to keep vertices at same vertical locations and will keep all red lines after hatch rather than remove them. 

 

Thank you.

0 Likes
Message 74 of 107

Sea-Haven
Mentor
Mentor

Do you mean like this. If not post an image or dwg.

 

SeaHaven_0-1720929511081.png

 

0 Likes
Message 75 of 107

saqib_tipa
Advocate
Advocate

@Sea-Haven 

Yes, similar to this but there will be no vertical lines on both ends and these should be created by lisp automatically.

In the image you can see example.

Colors are for example only.

Thank you.

 

Example.png

0 Likes
Message 76 of 107

john.uhden
Mentor
Mentor
@saqib_tipa ,
i just might do it for you.
Is it okay that the red copy has sides (to create a closed area for
hatching?
Ya know, since all the copies would be straight down in the Y direction,
this could be written to handle a selection set of polylines, as there
would be no need to individually select a direction.
Do you want the copied polylines on a certain layer (that already exists),
or just a certain color?

John F. Uhden

0 Likes
Message 77 of 107

saqib_tipa
Advocate
Advocate

@john.uhden 

I'll be thankful for that.

Yes, there should be vertical sides (left and right) created by lisp, keep them and not join to original line and copied line so that we can apply same command again.

Selection set of polylines is good and if it can do it both ways up OR down by user click (like in offset command) where we want that polyline to copy and hatch. 

Color and layer have no problem same color and layer is ok.

Thank you.

0 Likes
Message 78 of 107

Kent1Cooper
Consultant
Consultant

@saqib_tipa wrote:

.... there should be vertical sides (left and right) created by lisp, keep them and not join to original line and copied line so that we can apply same command again.

.... OR down by user click (like in offset command) where we want that polyline to copy and hatch. 

Color and layer have no problem same color and layer is ok. ....


Try this, edited from Message 35 [very lightly tested}.  You can Copy not only either up or down but in any direction, so you can use it on a generally vertical original and go sideways, etc. -- turn Ortho on if you want.  Edit the Hatch spacing number [1] as instructed.

 

(defun C:CCH ; = Copy, Close, and Hatch
  (/ *error* doc ss ent1 ent2)
  (defun *error* (errmsg)
    (if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break"))
      (princ (strcat "\nError: " errmsg))
    ); if
    (vla-endundomark doc)
    (princ)
  ); defun - *error*
  (vla-startundomark (setq doc (vla-get-activedocument (vlax-get-acad-object))))
  (prompt "\nObject to Copy, Close and Hatch: ")
  (if (setq ss (ssget "_:S+." '((0 . "LWPOLYLINE") (-4 . "<NOT") (-4 . "&") (70 . 1) (-4 . "NOT>")))); one, open only
    (progn ; then
      (setq
        ent1 (ssname ss 0)
        ss (ssadd ent1); re-use variable name
      ); setq
      (command-s "_.copy" ent1 "")
      (ssadd (setq ent2 (entlast)) ss)
      (command "_.line" "_non" (vlax-curve-getStartPoint ent1) "_non" (vlax-curve-getStartPoint ent2) "")
      (ssadd (entlast) ss)
      (command "_.line" "_non" (vlax-curve-getEndPoint ent1) "_non" (vlax-curve-getEndPoint ent2) "")
      (ssadd (entlast) ss)
      (command "_.hatch" "USER" "45" 1 "_no" ss ""); <-- EDIT 1 as preferred
    ); progn -- then
  ); if
  (vla-endundomark doc)
  (princ)
); defun -- C:CCH
(vl-load-com)
(prompt "\nType CCH to Copy, Close and Hatch an open Polyline.")

 

It could easily be adjusted to:

1)  allow selection of any open-ended object [Line, Arc, open Spline or Ellipse];

2)  allow selection of multiple objects, to be Copied/Closed/Hatched by the same distance and direction;

3)  ask for, rather than build in, things like Hatch angle or single/double, or pattern name, spacing/scale, rotation, etc.;

4)  control for Layer(s) of the new pieces.

Kent Cooper, AIA
0 Likes
Message 79 of 107

saqib_tipa
Advocate
Advocate

@Kent1Cooper 

Thank you so much for the code. I tried it and it works nicely.

It can copy and hatch at any direction as you told. I used it while ortho mode on and got copy and hatch.

One request, can you make this so that after selecting object it automatically selects displacement point anywhere or on selected line so that we just need to enter value.

Thank you.

 

0 Likes
Message 80 of 107

john.uhden
Mentor
Mentor

Thanks, @Kent1Cooper , well done.

You have saved me some work.

John F. Uhden

0 Likes