Visual LISP, AutoLISP and General Customization

Visual LISP, AutoLISP and General Customization

Reply
Valued Contributor
DavidGarrigues5269
Posts: 63
Registered: ‎12-10-2004
Message 1 of 9 (295 Views)
Accepted Solution

Copy Portion

295 Views, 8 Replies
09-12-2012 07:06 AM

Hey Everyone,

 

This kind of goes with the thread that was started up the other day called Distance Along Entity.  The difference is this time what  I want to do is get a copy of an entity, but not the whole entity only a portion of it.  In fact I would say that in the civil world we do this quite frequently.  We are constantly copying, breaking, erasing, etc only to get down to a portion of the original entity.  The problem really comes in when when you use polylines because sometimes after breaking them you end up with little segments that "busted" into more smaller pieces than what your orignal break should have created.  This command will walk a user through the process of taking an entity like a polyline and picking two points.  Those two points become break @ points.  Then it will prompt the user to select the entity that they want to keep. It will then erase the other items that we do not want.  I have posted it here for enjoyment and discussion.  My discussion is based upon is there a simpler way to do this meaning a little more cleaner for the user? I already assume that my code can be cleaner :-)

 

(defun c:CopyPortion ( / ent Beginthelastent NewLastEnt pt1 pt2 ss1 oldos ent2 ss2 ent2handle ss3 curent curentHandle)
  (setq ent (car (entsel "\nSelect the main entity to Copy: ")))
  ;(command "break" pause "f" pause pause "")
  (setq Beginthelastent (entlast))
  (command "copy" ent "" "" "")
  (setq NewLastEnt (entlast))
  (setq pt1 (getpoint "\nSelect the first point to break"))
  (setvar "cmdecho" 1)
  (setq ss1 (ssadd))
  (setq ss1 (ssadd  NewLastEnt ss1)) ;this one worked
  (setq oldos (getvar "osmode"))
  (setvar "osmode" 0)
  (command "break" ss1 pt1 pt1)
  (setvar "osmode" oldos)
  (princ "\nThe Original entity has been copied and and now broken into two or more objects")
  (setq pt2 (getpoint pt1 "\nSelect the second point to break \(can be the same point\): "))
  (defun SelectKeeper ()
    (princ "\nEverything is broken")
    (setq ent2 (car (entsel "\nSelect the entity you want to keep: ")))
    (setq ent2handle (cdr (assoc 5 (entget ent2))))
    (setq ss3 (ssadd))
    (setq curent (entnext Beginthelastent))
    (while curent
      (princ)
      (setq curentHandle (cdr (assoc 5 (entget curent))))
      (if (/= ent2handle curentHandle)
        (ssadd curent ss3)
      )
      (setq curent (entnext curent))
    )
    (command "erase" ss3 "")
  )
  (if (/= pt1 pt2)
    (progn
      (setq ent2 (car (entsel "\nSelect the new entity to be broken at second point: ")))
      (setq ss2 (ssadd))
      (setq ss2 (ssadd ent2 ss2))
      (setq oldos (getvar "osmode"))
      (setvar "osmode" 0)
      (command "break" ss2 pt2 pt2)
      (setvar "osmode" oldos)
      (SelectKeeper)
    )
    (SelectKeeper)
  )
)


DavidGarrigues5269 wrote:

AY CHIWAWA! 

Very nice.  I like it tons better.  I have to ask the question... as most of us are coordinate nervous, when do you think that the coordinate system would effect the outcome?

 

Thanks (I seem to be doing that a lot lately with you... I will never get tired of it)

....


You're welcome.  I can get seriously involved in something that I really think we'll have good use for.

 

The coordinate system could affect the outcome in a couple of ways, though I haven't dug into it too deeply yet, in relation to what this routine does.  Some Lisp functions return values based on the current Coordinate System, and some based on the WCS, and some are affected by the view direction.

 

The break points and the which-portion-to-keep point [which is actually a point, not a selected object, for reasons described in the code] will lie on the current construction plane, unless you use something like an Osnap mode that will tie them to the object.  The Break commands, and the (distance) functions that determine which portion to apply the second Break to and which one to keep, will find the location on the object that's closest to the point, in a 3D-perpendicular projection.

 

That means that if the object is not parallel to the current construction plane and/or not perpendicular to the current view direction, that projection could find a place on the object that's quite different from what you "see," and might not even fall on the object at all.  This could result in Breaking the object at the wrong place(s) or not at all, and/or finding the wrong portion to keep.  If it's not only not parallel but also significantly off the current plane in elevation, the found locations will be that much farther off.

 

If that all needs to be compensated for, I picture a bunch of (vlax-curve-getClosestPointToProjection) functions or something.  But if you draw things in the WCS, or if they're at least parallel to it and you're looking straight down at it [even if drawn things and/or the current construction plane are at non-0 elevations relative to it], it should work fine.

*Expert Elite*
Kent1Cooper
Posts: 5,779
Registered: ‎09-13-2004
Message 2 of 9 (285 Views)

Re: Copy Portion

09-12-2012 11:22 AM in reply to: DavidGarrigues5269

DavidGarrigues5269 wrote:

....what  I want to do is get a copy of an entity, but not the whole entity only a portion of it.  ....  We are constantly copying, breaking, erasing, etc only to get down to a portion of the original entity.  ....  This command will walk a user through the process of taking an entity like a polyline and picking two points.  Those two points become break @ points.  Then it will prompt the user to select the entity that they want to keep. It will then erase the other items that we do not want.  ....  is there a simpler way to do this meaning a little more cleaner for the user? ....


That really seemed like a useful thing to be able to do, so I really got into it -- try out the attached CopyPortion.lsp with its CPOR command.

 

 

Yes, it can be cleaner for the User.  A routine can be made to find the portion, after the first Break, that the second Break should be applied to, so you don't need to select it.  And it doesn't seem necessary to notify you that the original has been copied or that all the Breaking has been done [but you can add that back in if you want].  It can just ask for the object, and the one or two break points, and which resulting portion you want to keep.

 

Internally, there are simpler ways to do certain things, such as keep track of the broken pieces and decide which to Erase after you've chosen which to keep.  And what you are using handles for can be done without them, by using a different comparison function.

 

In addition, I came up with ways to:

::  Restrict selection to only breakable objects on unlocked Layers;

::  Prevent trying to Break a Circle at one point;

::  Work with Circles [given 2 break points], which need to be handled differently at the first Break than other objects;

::  Highlight things so you can see what you're working with;

::  Account for the fact that with non-continuous linetypes, since the gaps in the original and the broken pieces may not coincide, using (entsel) to select the portion you want to keep might find the original object instead;

::  Leave the retained portion selected/highlighted/gripped at the end, so you can not only see it distinguished from the longer original, but also grab a grip and move it, or pull down the Layer list and change its Layer, or give it a different color in the Properties box, or whatever you like.

 

And I put in an error handler.

 

[The one thing that's not included, but that I may work on later, is any accounting for the possible complications of different Coordinate Systems or view directions.]

Kent Cooper
Valued Contributor
DavidGarrigues5269
Posts: 63
Registered: ‎12-10-2004
Message 3 of 9 (280 Views)

Re: Copy Portion

09-12-2012 12:09 PM in reply to: Kent1Cooper

AY CHIWAWA! 

Very nice.  I like it tons better.  I have to ask the question... as most of us are coordinate nervous, when do you think that the coordinate system would effect the outcome?

 

Thanks (I seem to be doing that a lot lately with you... I will never get tired of it)

dg

*Expert Elite*
Kent1Cooper
Posts: 5,779
Registered: ‎09-13-2004
Message 4 of 9 (276 Views)

Re: Copy Portion

09-12-2012 12:51 PM in reply to: DavidGarrigues5269

DavidGarrigues5269 wrote:

AY CHIWAWA! 

Very nice.  I like it tons better.  I have to ask the question... as most of us are coordinate nervous, when do you think that the coordinate system would effect the outcome?

 

Thanks (I seem to be doing that a lot lately with you... I will never get tired of it)

....


You're welcome.  I can get seriously involved in something that I really think we'll have good use for.

 

The coordinate system could affect the outcome in a couple of ways, though I haven't dug into it too deeply yet, in relation to what this routine does.  Some Lisp functions return values based on the current Coordinate System, and some based on the WCS, and some are affected by the view direction.

 

The break points and the which-portion-to-keep point [which is actually a point, not a selected object, for reasons described in the code] will lie on the current construction plane, unless you use something like an Osnap mode that will tie them to the object.  The Break commands, and the (distance) functions that determine which portion to apply the second Break to and which one to keep, will find the location on the object that's closest to the point, in a 3D-perpendicular projection.

 

That means that if the object is not parallel to the current construction plane and/or not perpendicular to the current view direction, that projection could find a place on the object that's quite different from what you "see," and might not even fall on the object at all.  This could result in Breaking the object at the wrong place(s) or not at all, and/or finding the wrong portion to keep.  If it's not only not parallel but also significantly off the current plane in elevation, the found locations will be that much farther off.

 

If that all needs to be compensated for, I picture a bunch of (vlax-curve-getClosestPointToProjection) functions or something.  But if you draw things in the WCS, or if they're at least parallel to it and you're looking straight down at it [even if drawn things and/or the current construction plane are at non-0 elevations relative to it], it should work fine.

Kent Cooper
*Expert Elite*
Kent1Cooper
Posts: 5,779
Registered: ‎09-13-2004
Message 5 of 9 (253 Views)

Re: Copy Portion

09-13-2012 04:27 AM in reply to: DavidGarrigues5269

DavidGarrigues5269 wrote:

....what  I want to do is get a copy of an entity, but not the whole entity only a portion of it.  .... taking an entity like a polyline and picking two points.  Those two points become break @ points.  Then it will prompt the user to select the entity that they want to keep. ....


Another thought:  Is it a reasonable assumption that when you give it two break points on an open-ended object, the portion you want to keep is always the middle of the three resulting pieces?  After all, if what you want to keep is one of the end pieces, you wouldn't need two break points.

 

If that logic makes sense to you, I will see whether I can adjust the routine so that it automatically keeps the middle piece in that situation, and asks which portion to keep only if you gave it one break point for an open-ended object, or two break points for a closed one.

Kent Cooper
*Expert Elite*
Kent1Cooper
Posts: 5,779
Registered: ‎09-13-2004
Message 6 of 9 (230 Views)

Re: Copy Portion

09-17-2012 07:50 AM in reply to: Kent1Cooper

Kent1Cooper wrote:
.... 

In addition, I came up with ways to:

....

::  Prevent trying to Break a Circle at one point;

::  Work with Circles [given 2 break points], which need to be handled differently at the first Break than other objects;

....


I have found that there are more things that need special handling.  I was more conscious of the need to do Circles differently because the result after a Break becomes a different entity type.  But it turns out that you can't Break a closed Ellipse or Spline at a single point, either, and if you do it to a closed Polyline, under certain circumstances the result is two objects instead of one, and under one very particular circumstance, nothing happens.  I'm working on accounting for those issues, but if you use this on such things, be aware that the current version can give you either errors or unexpected results.

Kent Cooper
Valued Contributor
DavidGarrigues5269
Posts: 63
Registered: ‎12-10-2004
Message 7 of 9 (225 Views)

Re: Copy Portion

09-17-2012 08:25 AM in reply to: Kent1Cooper

You are addicted... I love it!

Contributor
cadmentr
Posts: 11
Registered: ‎03-28-2011
Message 8 of 9 (113 Views)

Re: Copy Portion

02-12-2014 05:32 PM in reply to: Kent1Cooper
I found your info on the forums. Is there a way that your copy portion could be applied using a rectangular selection set?

As your original requester mentioned when working with huge civil drawings with hundreds of layers and several counties in Southern Ontario, it would be most advantageous, to be able to just copy a portion of the area that you are required to work with.

Like using the crop command in Photoshop, to get the area you want to use.

Regards, Adriana West (cadmentr)
*Expert Elite*
Kent1Cooper
Posts: 5,779
Registered: ‎09-13-2004
Message 9 of 9 (91 Views)

Re: Copy Portion

02-13-2014 04:46 AM in reply to: cadmentr

cadmentr wrote:
.... Is there a way that your copy portion could be applied using a rectangular selection set?
...
Like using the crop command in Photoshop, to get the area you want to use.
....

It may be, though I think it would be complicated.  I'm thinking in particular about something like contour lines that may cross in and out of the crop boundary, perhaps multiple times, and how a routine would figure out which parts to keep, etc.  Also, finding the intersections of things like a boundary rectangle and drawn elements that lie in the same plane isn't too complicated, but if you've got contours at actual non-zero elevations, I think you'd need to Flatten them down, which would lose valuable information.

 

In lieu of that, I would suggest either:

 

A)  Use an Xclipped Xref or a Paper Space Viewport sized to the desired area, both of which have the advantages that:

  1)  any change to the overall or base or source drawing will be reflected where you're working, and won't also need to be changed in the copy [because it won't be a separate set of entities], and

  2)  you can very easily change the shape of the working area without needing either [in the case of enlarging it] to replace any elements with new copies that extend farther, or [in the case of reducing it] to Trim anything more;

 

or:

 

B)  If you really need a separate set of entities and don't mind the drawbacks of that, Copy everything, draw a rectangle [or, for that matter, other shape] defining the desired area, and Search the Forums for something like "Trim outside Polyline" [there are routines here that will Trim off everything outside a Polyline boundary].

Kent Cooper
Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Are You Going To Be @ AU 2014? Feel free to drop by our AU topic post and share your plans, plug a class that you're teaching, or simply check out who else from the community might be in attendance. Ohh and don't forgot to stop by the Autodesk Help | Learn | Collaborate booths in the Exhibit Hall and meet our community team if you get a chance!