toper Posted May 20, 2011 Share Posted May 20, 2011 So new to LISP it's ridiculous, and I need help. I'm doing some designs for lighting and sound, and I have sets of blocks at various points around a floorplan. I plan on making these blocks (dynamic blocks if necessary) and giving them similar nomenclature according to what they are (speakers, monitors, motors, trusses, etc.). Now, rather than going through and measuring the distance by hand, so to speak, for every single item, I'd love to find a LISP routine where I can insert a custom (like 200, 0) insertion point to measure from, and measure each (or batch) block's distance from that point. If the results could be posted in a table, that would be even more awesome. Presumably I would use the names of the similar blocks, as in, any block with the word "motor" in its tag or name. I sense I am asking for something rather big here... Quote Link to comment Share on other sites More sharing options...
BlackBox Posted May 20, 2011 Share Posted May 20, 2011 This should get you started: (defun c:FOO (/ pt) (if (setq pt (getpoint "\nSpecify base point: ")) (while (and (not (initget 32)) (/= nil (setq pt2 (getpoint pt "\nSpecify point to measure: ")))) (prompt (strcat "\n >> Distance >> " (rtos (distance pt pt2) 2 2)))) (prompt "\n** Invalid point ** ")) (princ)) There are plenty of things that can be done to improve this as well... Enjoy! Quote Link to comment Share on other sites More sharing options...
toper Posted May 20, 2011 Author Share Posted May 20, 2011 Thanks RenderMan! This is an excellent starting point for me. Gives me a base to start with and I can click on as many objects as I want and it specifies a separate distance for each, not a total (which is good, I don't want a total). Now if I can figure out a a way to get the routine to automatically select all objects/blocks with a name starting with "###" and give me a list of all those measurements...I'd be even happier. The struggle goes on. And oh yea, next thing: What I need to do ideally, which I just realized, is this: The measurement I need to create is an X,Y coordinate. So I'd need to measure from a basepoint (say, a midpoint on a back wall), then a distance along X to a point where I then up Y to the object, creating two separate distances. Does this make sense? Quote Link to comment Share on other sites More sharing options...
Tharwat Posted May 20, 2011 Share Posted May 20, 2011 Hope you do not mind dear Renderman . Just an idea . (defun c:Test (/ p ss i pt e) (if (and (setq p (getpoint "\n Specify Starting point :")) (setq ss (ssget "_:L" '((0 . "INSERT")))) ) (repeat (setq i (sslength ss)) (setq sset (ssname ss (setq i (1- i)))) (setq pt (cdr (assoc 10 (setq e (entget sset))))) (print (strcat ">> * Distance between Sarting point to Block :" (cdr (assoc 2 e)) "is :" (rtos (distance p pt) 2) ) ) ) (princ) ) (princ) ) Tharwat Quote Link to comment Share on other sites More sharing options...
BlackBox Posted May 20, 2011 Share Posted May 20, 2011 (edited) Thanks RenderMan! This is an excellent starting point for me. You're welcome. Now if I can figure out a a way to get the routine to automatically select all objects/blocks with a name starting with "###" and give me a list of all those measurements...I'd be even happier. The struggle goes on. Welcome to the world of selection sets! This exampe assumes you're measuring from the base point to the insertion point of each block selected: (defun c:FOO (/ pt ss oBlock) (vl-load-com) (if (and (setq pt (getpoint "\nSpecify base point: ")) (setq ss (ssget '((0 . "INSERT") ;|(2 . "###*")|))) ((lambda (i / e) (while (setq e (ssname ss (setq i (1+ i)))) (prompt (strcat "\n >> Distance >> " (rtos (distance pt (vlax-get (setq oBlock (vlax-ename->vla-object e)) 'insertionpoint)) 2 2) ", to " (vla-get-effectivename oBlock))))) -1) (cond (pt (prompt "\n** Nothing selected ** ")) ((prompt "\n** Invalid point ** ")))) (princ)) ... Not sure if I have enough information for you to correlate the distance to a specific entity yet, though. [edit] BTW - It is unclear if you meant "###" is the actual prefix to your block names, or if that was a generic annotation for number-number-number (i.e., 123*, or 456*, etc.). [/edit] And oh yea, next thing: What I need to do ideally, which I just realized, is this: The measurement I need to create is an X,Y coordinate. So I'd need to measure from a basepoint (say, a midpoint on a back wall), then a distance along X to a point where I then up Y to the object, creating two separate distances. Does this make sense? No, not at all... Perhaps a screen shot would help? Edited May 20, 2011 by BlackBox Corrected else statement Quote Link to comment Share on other sites More sharing options...
toper Posted May 20, 2011 Author Share Posted May 20, 2011 I love this forum. Intelligent people actually respond. This takes the LISP to the next step, I can select multiple objects and then get a set of distances as a result, rather than doing one at a time. Next steps are: * Determine the coordinates along the X and Y axes from the base point to each object. * Then, if possible, have the ability to enter a name prefix and the LISP function would determine those X & Y coordinates for all objects (or blocks w/ attributes?) that contain that name prefix. I appreciate so much any help being offered. Trying to work through the code on my own, but I fear little progress will get made. But I try, nonetheless! Quote Link to comment Share on other sites More sharing options...
BlackBox Posted May 20, 2011 Share Posted May 20, 2011 I love this forum. Intelligent people actually respond. That's very kind of you to say. This takes the LISP to the next step, I can select multiple objects and then get a set of distances as a result, rather than doing one at a time. That's the point - programming allows us to take repaeted tasks, or sequences of, and automate them to increase efficiency. Next steps are: Whoa, whoa, whoa, there buddy... you're going to have to crack open the Developer Documentation and start reading for yourself here, real soon. * Determine the coordinates along the X and Y axes from the base point to each object. This is a bit confusing to me. Are you interested in the X,Y of the blocks insertion point, or the angle from the base point to same? * Then, if possible, have the ability to enter a name prefix and the LISP function would determine those X & Y coordinates for all objects (or blocks w/ attributes?) that contain that name prefix. Yes, simply store a user input string to a variable/symbol, then supply that value to the appropriate DXF code for your ssget filter, walla. I appreciate so much any help being offered. Trying to work through the code on my own, but I fear little progress will get made. But I try, nonetheless! Shortly here, you'll have the opportunity (responsability) of writing & posting your own code, so that we see you're doing some of your own work (or at least making genuiine effort), and we'll help from there. Just remember, everyone here is a volunteer... as long as you're polite, and respectful, we're happy to help. Quote Link to comment Share on other sites More sharing options...
toper Posted May 20, 2011 Author Share Posted May 20, 2011 Yea my babbling was a little confusing, this is the way I need to measure distance, so my riggers can walk the floor precisely to the spot where (above them) the lights will be hung, speaker boxes hung, etc. Thanks again. I'm working myself, too, but at this point my coding skills are worthy of, well, nothing. I will definitely pitch in when I start getting at least a little proficient. The "next step" was just me thinking out loud, not to worry. Quote Link to comment Share on other sites More sharing options...
BlackBox Posted May 20, 2011 Share Posted May 20, 2011 Is there a block located at the final destination (you only show the midpoint of what I beleive to be a wall)? Otherwise, the distance and coordinate extraction is not a problem. Quote Link to comment Share on other sites More sharing options...
toper Posted May 20, 2011 Author Share Posted May 20, 2011 The block on the left (long thin rectangle) is my 2-second scribble representation of a wall. So the measuring is going from the wall point on the left up to the square. I'm combing through AutoCAD's documentation on this too. So far I'm finding mostly general, broad-strokes sort of information, but that's probably because I don't know what to look for as well yet. Quote Link to comment Share on other sites More sharing options...
BlackBox Posted May 20, 2011 Share Posted May 20, 2011 The block on the left (long thin rectangle) is my 2-second scribble representation of a wall. So the measuring is going from the wall point on the left up to the square. This is the part I need for you to be more specific. At the destination point you show, will there be (is there) a block representing the device (i.e., monitor, speaker, etc.), or is the square-like shape the block itself, and the destination point shown is that blocks insertion point? Also, what is your block naming conventions (i.e., "Monitor_001", "001-speaker", etc.)? Try to be as specific as possible, for each of the blocks you 'd like to use this routine on. Quote Link to comment Share on other sites More sharing options...
toper Posted May 20, 2011 Author Share Posted May 20, 2011 Gotcha. Sorry, the LISP language is literally new to me as of Wednesday. I plan on spending the rest of the next few weeks in my spare time trying to get my head around programming for LISP. The naming will be keyword first, so, Box_001 or GoBo_001, etc. So in this drawing I'll call the square "Box_001". The basepoint is against the middle of that rectangle on the left, which represents a wall. So when the script runs and asks me to Specify Base point, that's where I'm starting in this example. The point on the blocks can be anywhere, but I think I'll make it the midpoint on the bottom edge. The weird-looking shape in the bottom of the drawing can be ignored. Quote Link to comment Share on other sites More sharing options...
BlackBox Posted May 20, 2011 Share Posted May 20, 2011 Gotcha. Sorry, the LISP language is literally new to me as of Wednesday. I plan on spending the rest of the next few weeks in my spare time trying to get my head around programming for LISP. The naming will be keyword first, so, Box_001 or GoBo_001, etc. So in this drawing I'll call the square "Box_001". The basepoint is against the middle of that rectangle on the left, which represents a wall. So when the script runs and asks me to Specify Base point, that's where I'm starting in this example. The point on the blocks can be anywhere, but I think I'll make it the midpoint on the bottom edge. The weird-looking shape in the bottom of the drawing can be ignored. No worries. This weekend, read up on the Developer Documentation, and pay special attention to the cond funtion. Also, if you can, read up on the quadrants (i.e., half pi, pi, one and a half pi, and two pi, or zero pi), as you're going to use this to determine the orientation of the destination point, in relation to the base point. If you're really feeling ambitious, write some code, experiment... for example in the scenario you posted, pick your base point, and your destination point, and try to work out how to find that point of intersection if you will. Here's some hints -> look into the car, cadr, and last functions. Good luck! Quote Link to comment Share on other sites More sharing options...
toper Posted May 20, 2011 Author Share Posted May 20, 2011 I'll do some reading, and thanks for your help. I'll let you know if/when I figure it out. Quote Link to comment Share on other sites More sharing options...
BlackBox Posted May 20, 2011 Share Posted May 20, 2011 I'll do some reading, and thanks for your help. I'll let you know if/when I figure it out. I'll be happy to continue helping... see what you can do over the weekend, and post the code you can come up with. We'll go from there... the point is to get started, put forth your best effort, then get some input on how better to do the same thiing ( [edit] I'll be the first to tell you that I'm still learning, in many respects [/edit] Have a good weekend! Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted May 20, 2011 Share Posted May 20, 2011 Maybe this will get you started: (defun c:test ( / _pt->str en fn fo i p1 p2 ss ) (defun _pt->str ( pt ) (apply 'strcat (mapcar 'strcat (mapcar 'rtos pt) '(","","""))) ) (if (and (setq p1 (getpoint "\nSpecify Base Point: ")) (setq ss (ssget '((0 . "INSERT")))) (setq fn (getfiled "Output File" "" "txt" 1)) (setq fo (open fn "w")) ) (progn (setq i -1 p1 (trans p1 1 0)) (write-line (strcat "From Base: " (_pt->str p1)) fo) (write-line "Block\tInsertion\tDx,Dy" fo) (while (setq en (ssname ss (setq i (1+ i)))) (setq p2 (cdr (assoc 10 (entget en)))) (write-line (strcat (cdr (assoc 2 (entget en))) "\t" (_pt->str p2) "\t" (_pt->str (mapcar '- p2 p1))) fo) ) (close fo) (startapp "notepad" fn) ) ) (princ) ) Will write the values to a file of your choosing Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.