PDA

View Full Version : LISP Blocks intersecting clean up help.



james.hodson
2009-12-07, 05:42 PM
Wow that was a hard title to name...

I am in need of help. I am looking for a LISP that will look at my drawing, look at a specific block (preferably one I click on) and then searches that drawing for where it has lines or text or something intersecting it, then move it away from that object.

I know I am asking for a pretty complex subroutine. I have attached a sample of what I am looking to do. Please see the rev clouds. I have attribute blocks that intersect walls and other text that I would like a lisp that automatically moves the attributs (lines of text only) that intersects and places them in a new location.

Can someone please help?

James Hodson


PS My office uses AutoCAD 2004/2009, and we save in 2000 format, I figure that might be important to know.

fixo
2009-12-08, 09:11 AM
Wow that was a hard title to name...

I am in need of help. I am looking for a LISP that will look at my drawing, look at a specific block (preferably one I click on) and then searches that drawing for where it has lines or text or something intersecting it, then move it away from that object.

I know I am asking for a pretty complex subroutine. I have attached a sample of what I am looking to do. Please see the rev clouds. I have attribute blocks that intersect walls and other text that I would like a lisp that automatically moves the attributs (lines of text only) that intersects and places them in a new location.

Can someone please help?

James Hodson


PS My office uses AutoCAD 2004/2009, and we save in 2000 format, I figure that might be important to know.
Not sure about it will helps
You can just move attributes by clicking on it
Tested on 2008 only



(defun C:MATT (/ att att_obj base ent pt)
(while
(setq ent (nentsel "\nSelect attribute (or press Enter to Exit): "))
(setq att (car ent)
base (cadr ent)
att_obj (vlax-ename->vla-object att)
pt (getpoint base "\nSpecify new point: ")
)
(vlax-invoke att_obj 'Move base pt)
)
(princ)
)
(prompt "\n\t\t>>>\tType MATT to move attribute(s)\t<<<")
(prin1)
(vl-load-com)


~'J'~

Steve.K
2009-12-08, 10:30 AM
James, I'd say fixo's solution is probably the best you're going to get. Your particular case is more complex because it involves attributes.

To lispers: because I've seen a few "move overlapping text" requests before, I was thinking about it today, and just thinking out loud now (can an experienced lisper comment if they think it'd work - not asking you to do it!), if it was just text objects you had to move could a primitive version be done by:
- getting a boundingbox of the object (a block is ideal, but even a line)
- ssget a fence of that boundingbox getting all overlapping text.
- moving any infringing text away a set distance (eg north)
- and then depending how complex you go you could make some sort of fence around that text to check if anything in inside of where you moved it to overlaps, and opt to move it to a different location (eg south).
Possible? Practical?

steve

irneb
2009-12-08, 01:02 PM
Probably possible. I'd advise not doing the 2nd move automatically, rather ask the user to place it manually then - otherwise you could end up with a never-ending loop and freeze AC.

If it's simply going to check the bounding box then it should be simple as you've described. It's possible to get a rectangular bounding box of any entity (blocks / text / etc) quite easily, but to get a "wrapped" bounding profile is very difficult - there is something like that already (maybe could be used here).

james.hodson
2009-12-08, 10:02 PM
Well is there a way to creat a bounding box and fence based upon user clicks on specific attributes, and then have it move it as described by steve?

I mean that would work just fine for me if I could click on say two attributes ("n1L1." & "D001") and it would automatically move it to the first location it can find that is obstruction free?

James

james.hodson
2009-12-08, 10:11 PM
Is there a way this code will accept more than one click within an attribute (my attribute blocks usually have two specific attributes I need to move, if I could move two at once with the same destination click that would be very awesome and pretty much what I need.

regards,
James



(defun C:MATT (/ att att_obj base ent pt)
(while
(setq ent (nentsel "\nSelect attribute (or press Enter to Exit): "))
(setq att (car ent)
base (cadr ent)
att_obj (vlax-ename->vla-object att)
pt (getpoint base "\nSpecify new point: ")
)
(vlax-invoke att_obj 'Move base pt)
)
(princ)
)
(prompt "\n\t\t>>>\tType MATT to move attribute(s)\t<<<")
(prin1)
(vl-load-com)

Steve.K
2009-12-08, 10:44 PM
Probably possible. I'd advise not doing the 2nd move automatically, rather ask the user to place it manually then - otherwise you could end up with a never-ending loop and freeze AC.

If it's simply going to check the bounding box then it should be simple as you've described. It's possible to get a rectangular bounding box of any entity (blocks / text / etc) quite easily, but to get a "wrapped" bounding profile is very difficult - there is something like that already (maybe could be used here).
Thanks for the comments! True, bounding box is not exactly ideal if you are doing it on a diagonal line for instance. This "wrapped" bounding box I've never come across, but it would be a great function to have if it exists...?


Well is there a way to creat a bounding box and fence based upon user clicks on specific attributes, and then have it move it as described by steve?
I mean that would work just fine for me if I could click on say two attributes ("n1L1." & "D001") and it would automatically move it to the first location it can find that is obstruction free?

James, the problem is the part you want automatically is the most difficult part, and likely the most error prone. Apart from asking the user, what other way is there to move the text to a vacant area except by trial and error? As irneb said, it could just remain in an infinite loop, or it could end up somewhere you can't find it!

james.hodson
2009-12-08, 11:04 PM
James, the problem is the part you want automatically is the most difficult part, and likely the most error prone. Apart from asking the user, what other way is there to move the text to a vacant area except by trial and error? As irneb said, it could just remain in an infinite loop, or it could end up somewhere you can't find it!

Well then the matt.lsp would work just fine for me, as long as I can choose two attribute at once and then pick a new destination point and then they both go.

regards,
James

irneb
2009-12-09, 05:23 AM
Thanks for the comments! True, bounding box is not exactly ideal if you are doing it on a diagonal line for instance. This "wrapped" bounding box I've never come across, but it would be a great function to have if it exists...?I was thinking about the "ShrinkWrap" command in some of the verticals to ACad. If you search this forum for the word shrinkwrap there's 3 threads. But basically I think this (http://www.cadtutor.net/forum/showthread.php?t=23056) should be a good starting point.


Well then the matt.lsp would work just fine for me, as long as I can choose two attribute at once and then pick a new destination point and then they both go.

regards,
JamesThat one only moves the attributes, not the entire tag. But if that's actually what you want, try this (modified for multiple attribs & added comments):
(vl-load-com)
(defun C:MATT1 (/ att att_obj base ent lst pt)
(while (setq ent (nentsel "\nSelect attribute (or press Enter to Stop): ")) ;Ask user to select
(setq lst (cons ent lst)) ;Add to the list
) ;_ end of while
(setq lst (reverse lst)) ;Reorder the list as per selected
(setq base (cadr (car lst))) ;Get the base point as the point selected for 1st attrib
(setq pt (getpoint base "\nSpecify new point: ")) ;Ask user for new point

(foreach ent lst ;Loop through all selected entities
(setq att (car ent) ;Get only the ename of selected attrib
att_obj (vlax-ename->vla-object att) ;Get the ActiveX object of the entity
) ;_ end of setq
(vlax-invoke att_obj 'Move base pt) ;Move the object
) ;_ end of foreach
(princ)
) ;_ end of defunAsks you to select multiple attributes and moves them in one go.

fixo
2009-12-09, 07:12 AM
I was thinking about the "ShrinkWrap" command in some of the verticals to ACad. If you search this forum for the word shrinkwrap there's 3 threads. But basically I think this (http://www.cadtutor.net/forum/showthread.php?t=23056) should be a good starting point.

That one only moves the attributes, not the entire tag. But if that's actually what you want, try this (modified for multiple attribs & added comments):
Thanks for saveing my time :)

~'J'~

Steve.K
2009-12-10, 01:50 AM
I was thinking about the "ShrinkWrap" command in some of the verticals to ACad. If you search this forum for the word shrinkwrap there's 3 threads. But basically I think this (http://www.cadtutor.net/forum/showthread.php?t=23056) should be a good starting point.
Thanks for the link. Seems like everyone who asks about it ends up there. That ECO by Vladamir is excellent! Talk about cramming code into a tight space! Hopefully I can find a list of points in that brilliant mess.

irneb
2009-12-10, 09:28 AM
Yep, after "reading" a few lines of his code my brain goes fuzzy :lol: I don't speak Cyrillic :mrgreen:. Oh well I could try Google's translate ...

Steve.K
2010-01-15, 11:19 PM
Just for furture searches. Here's a more up-to-date link to Vladimir's ECO program (http://www.theswamp.org/index.php?topic=26664.0).