Tharwat Posted July 4, 2011 Share Posted July 4, 2011 Dude... I don't even know what you've just written (I'm going to need to let that soak in a bit)... but it looks like it does a whole lot more then just selecting and deleting all the hatches in the region specified... Can you explain that a bit? And for future reference, can you explain where I went wrong with my original ssget code? Edit: I just added your ssget replacement code into my code, and while it worked, it wasn't the cleanest (see second code box below) (vl-cmdf "_.erase" (if (and (setq ss (ssget "_c" (list (car (vlax-safearray->list mx)) (cadr (vlax-safearray->list my)) ) (list (- (car (vlax-safearray->list mx)) 10) (+ (cadr (vlax-safearray->list my)) 10) ) ) ) (setq l (ssadd)) ) (progn (repeat (setq i (sslength ss)) (setq sset (ssname ss (setq i (1- i)))) (if (eq (cdr (assoc 0 (entget sset))) "HATCH") (setq lst (ssadd sset l)) ) ) (if lst (princ (strcat "No of found Hatches: " (itoa (sslength lst))) ) (princ "\n No hatches found !! ") ) ) (princ) ) "" ) Resulted in: No of found Hatches 1_.erase Select objects: No of found Hatches 1 *Invalid selection* Expects a point or Window/Last/Crossing/BOX/ALL/Fence/WPolygon/CPolygon/Group/Add/Remove/Multiple/P revious/Undo/AUto/SIngle/SUbobject/Object Select objects: Command: Why don't you ask your question completely instead of asking for a part , and after that you modify the code wrongly and return the mistake to the provider . Quote Link to comment Share on other sites More sharing options...
Tharwat Posted July 4, 2011 Share Posted July 4, 2011 BTW, when using the SelectionSet functions, such as ssadd, ssdel etc, you don't need to reassign the SelectionSet to the variable, since the SelectionSet is updated and the variable will point to this updated set. I explain this concept a little more in this post. You witness the same behaviour when dealing with Entity Names and VLA-Objects. Thanks a lot , Point taken . Regards. Quote Link to comment Share on other sites More sharing options...
Hickoz_bro Posted July 4, 2011 Author Share Posted July 4, 2011 Tharwat - Sorry... I was a little surprised by your response there, there was a whole lot of new things in there I haven't seen before (I'm new at this remember) so I wasn't really sure where to start. I spend a good hour or so trying to understand the various methods etc you've used, and while I understand each line on its own, I don't understand the code as a whole. It looks to me as though it gets all objects in the given window, then generates a list of those objects, from that it generates another selection set of the objects who's object name = HATCH. This just seems unnecessarily complicated... Lee Mac - Thanks for that... I'm not surprised it was something as simple as the spaces... I didn't realize that was an issue (not that I noticed it at all). Yes I'm using the VLIDE, but even after you mentioned that it would show me the error, I didn't spot it... I had to look much harder, turns out the only difference is the colour of the '.' character... It really isn't that obvious at all. P.S. I liked the post you linked to about the VLIDE, I learnt a few new things from that... Thanks for the help guys... I'm just about done with this code now... I'll post it up when I'm done so you can tell me where I went wrong... Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted July 4, 2011 Share Posted July 4, 2011 Lee Mac - Thanks for that... I'm not surprised it was something as simple as the spaces... I didn't realize that was an issue (not that I noticed it at all). In the majority of cases it wouldn't be a problem since LISP doesn't evaluate whitespace, however the problem arose because the list was being interpreted as: (0.0"HATCH") instead of: (0 . "HATCH") Yes I'm using the VLIDE, but even after you mentioned that it would show me the error, I didn't spot it... I had to look much harder, turns out the only difference is the colour of the '.' character... It really isn't that obvious at all. I suppose its what you get used to - after writing a few thousand lines of code, those kinds of mistakes tend to jump out at you. P.S. I liked the post you linked to about the VLIDE, I learnt a few new things from that.. Thanks mate, glad you could understand my tutorials Quote Link to comment Share on other sites More sharing options...
Hickoz_bro Posted July 4, 2011 Author Share Posted July 4, 2011 Okay... I've got it now... I had to modify Lee Mac's suggestion a little... He suggested this: (setq mx (vlax-safearray->list mx) my (vlax-safearray->list my) ) But it didn't like it. Seems to me that you can't setq mx to some function of mx (cyclic dependency we'd say in Inventor)... So I simply made it: (setq mx2 (vlax-safearray->list mx) my2 (vlax-safearray->list my) ) and that seems to work well... So... What I'm left with now is this: (defun c:TEST2 (/ actdoc actspc eName my my2 mx mx2) (vl-load-com) (setq actdoc (vla-get-activedocument (vlax-get-acad-object)) actspc (vlax-get-property actdoc (if (= 1 (getvar 'CVPORT)) 'Paperspace 'Modelspace ) ) ) (if (setq eName (car (entsel "\n >> Select Object >> "))) (progn (vla-getboundingbox (vlax-ename->vla-object eName) 'my 'mx) (princ (list (car (vlax-safearray->list mx)) (cadr (vlax-safearray->list my)) ) ) (setq mx2 (vlax-safearray->list mx) my2 (vlax-safearray->list my) ) (if (setq ss (ssget "_C" (list (car mx2) (cadr my2)) (list (- (car mx2) 10) (+ (cadr my2) 10)) '((0 . "HATCH")) ) ) (command "_.erase" ss "") ) (vla-insertblock actspc (vlax-3d-point (list (+ (car mx2) 4.35) ;For some reason these blocks don't insert with correct origin; (+ (cadr my2) 18.63) ;Hence coordinate adjustments (+4.35 & +18.63)... Figure this out later; ) ) "\\\\ServerName\\NetworkDrive\\CompanyLogo.dwg" 1 1 1 0 ) ) ) (princ) ) What it does is prompt the user to select an object (ideally the boundary of the label we're producing) then it deletes any hatching (old company logo) from the bottom right corner, and it replaces it with a AutoCAD block (new company logo)... I'll remove the user input bit next, so that it automatically selects the outer most loop of the drawing. Thanks again for your help guys. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted July 4, 2011 Share Posted July 4, 2011 Seems to me that you can't setq mx to some function of mx Yes, you can, here is the corrected code: (defun c:test2 ( / actdoc actspc ename mx my object ss ) (vl-load-com) (setq actdoc (vla-get-activedocument (vlax-get-acad-object)) actspc (vlax-get-property actdoc (if (= 1 (getvar 'CVPORT)) 'Paperspace 'Modelspace)) ) (if (and (setq eName (car (entsel "\n >> Select Object >> "))) (vlax-method-applicable-p (setq object (vlax-ename->vla-object eName)) 'getboundingbox) ) (progn (vla-getboundingbox object 'my 'mx) (setq mx (vlax-safearray->list mx) my (vlax-safearray->list my) ) (if (setq ss (ssget "_C" (list (car mx) (cadr my)) (list (- (car mx) 10) (+ (cadr my) 10)) '((0 . "HATCH")) ) ) (command "_.erase" ss "") ) (vla-insertblock actspc (vlax-3d-point (list (+ (car mx) 4.35) (+ (cadr my) 18.63) 0.0)) "\\\\ServerName\\NetworkDrive\\CompanyLogo.dwg" 1.0 1.0 1.0 0.0 ) ) ) (princ) ) However, note that the above doesn't check for the existence of the block. Quote Link to comment Share on other sites More sharing options...
Hickoz_bro Posted July 4, 2011 Author Share Posted July 4, 2011 Yeah, that's worked well... Thanks heaps... Not sure why it bombed out when I tried using... (setq mx (vlax-safearray->list mx) my (vlax-safearray->list my) ) ...the first time, Oh well... no biggy... Now that we've got this far, can you help explain a few things in terms of the layout?? We've started with (setq actdoc (vla-get-activedocument (vlax-get-acad-object)) actspc (vlax-get-property actdoc (if (= 1 (getvar 'CVPORT)) 'Paperspace 'Modelspace)) ) This to me looks similar to declaring variables (DIM) in VBA... so we're starting by organising some building blocks... Then we go: (if Since the expression that is evaluated by the IF command, I'm assuming this is to validate whether or not something has been selected... and since most the working code is in the if=true brackets, I understand it to mean 'if object is selected, then continue, else do nothing'. Is this right? Next we have: (and (setq eName (car (entsel "\n >> Select Object >> "))) (vlax-method-applicable-p (setq object (vlax-ename->vla-object eName)) 'getboundingbox) ) Since we've got the (and) bit in there, I'm assuming this means the user has to select an object, and that object as to have a valid bounding box? so I guess if you were to select a point object it might not work? I'm pretty confident I understand what's going on inside the (Progn) brackets, although I have to wonder why we decided that (command "_.erase" ss "") was the most efficient way to erase the objects... I'm assuming that vla-erase or vl-cmdf "_.erase" would work just as well? Thanks again for your help guys.. I've learnt heaps with this little exercise... Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted July 4, 2011 Share Posted July 4, 2011 We've started with (setq actdoc (vla-get-activedocument (vlax-get-acad-object)) actspc (vlax-get-property actdoc (if (= 1 (getvar 'CVPORT)) 'Paperspace 'Modelspace)) ) This to me looks similar to declaring variables (DIM) in VBA... so we're starting by organising some building blocks... Similar, but we don't have to declare variables in LISP since in LISP a variable can hold multiple data types throughout the code [as also demonstrated in this code by the (setq mx (vlax-safearray->list mx)) ]. I set these variables first since I am likely to use the ActiveSpace or ActiveDocument frequently throughout the code and it is bad practice (and slow) to repeatedly call (vlax-get-acad-object) and go through the object model hierarchy. Then we go: (if Since the expression that is evaluated by the IF command, I'm assuming this is to validate whether or not something has been selected... and since most the working code is in the if=true brackets, I understand it to mean 'if object is selected, then continue, else do nothing'. Is this right? Correct, the expression following the 'if' statement must return non-nil for the code to evaluate the 'then' statement of the 'if' function. Next we have: (and (setq eName (car (entsel "\n >> Select Object >> "))) (vlax-method-applicable-p (setq object (vlax-ename->vla-object eName)) 'getboundingbox) ) Since we've got the (and) bit in there, I'm assuming this means the user has to select an object, and that object as to have a valid bounding box? so I guess if you were to select a point object it might not work? Correct, except I am testing whether the selected object has the 'getboundingbox' method available for us to call. I'm pretty confident I understand what's going on inside the (Progn) brackets, although I have to wonder why we decided that (command "_.erase" ss "") was the most efficient way to erase the objects... I'm assuming that vla-erase or vl-cmdf "_.erase" would work just as well? Yes, you could use vl-cmdf instead of command (it wouldn't really make a difference in this case), or iterate through the SelectionSet and use either entdel (or vla-delete) on each entity (or VLA-Object). Quote Link to comment Share on other sites More sharing options...
Hickoz_bro Posted July 4, 2011 Author Share Posted July 4, 2011 Okay, I'm trying to find info on these functions (in bold), but I can't find any, can you point me in the right direction? EDIT: I got it... Found the reference link on your page: http://docs.autodesk.com/ACD/2011/ENU/filesALR/WSfacf1429558a55de1a7524c1004e616f8b-5913.htm It looks to be like this bit: ([b]vlax-method-applicable-p[/b] (setq object ([b]vlax-ename->vla-object eName[/b])) 'getboundingbox) is getting the bounding box of object 'eName' and saving it to 'object'... Then in this bit: (vla-getboundingbox object 'my 'mx) we extract the lower left, and upper right points from the boundingbox object and save them to 'my and 'mx... Question is... Why did we save the bounding box object to 'object' in the first place? Does it contain other information we could use later? Or is this just 'good practice' to break it into smaller steps? Thanks again... Quote Link to comment Share on other sites More sharing options...
Hickoz_bro Posted July 5, 2011 Author Share Posted July 5, 2011 BOOYAH! Thanks for the help guys... I just swapped out the bit where I get user input, and replaced it with another ssget but then I found that the (vlax-ename->vla-object eName) bit failed 'cause ssget returns a selection set and entsel returns the entity name in a list... so I found ssname which got the name of the first item from the selection set... just what I wanted... I suspect there's probably another way to do it... but this works for me... Keen to hear your suggestions though if you have any... (defun c:test3 (/ actdoc actspc eName mx my object ss) (vl-load-com) (setq actdoc (vla-get-activedocument (vlax-get-acad-object)) actspc (vlax-get-property actdoc (if (= 1 (getvar 'CVPORT)) 'Paperspace 'Modelspace ) ) ) (setq ss nil) (if (and (if (setq ss (ssget "_C" (list 0.0 0.0) (list 1.0 1.0) '((0 . "LWPOLYLINE")) ) ) (progn(setq eName (ssname ss 0)) (princ "\nFound Objects!\n") ) (princ "\nNo Objects Found!\n") ) (vlax-method-applicable-p (setq object (vlax-ename->vla-object eName)) 'getboundingbox)) (progn (vla-getboundingbox object 'my 'mx) (setq mx (vlax-safearray->list mx) my (vlax-safearray->list my) ) (if (setq ss (ssget "_C" (list (car mx) (cadr my)) (list (- (car mx) 10) (+ (cadr my) 10)) '((0 . "HATCH")) ) ) (command "_.erase" ss "") ) (vla-insertblock actspc (vlax-3d-point (list (+ (car mx) 4.35) (+ (cadr my) 18.63) 0.0) ) "\\\\Hdnt10\\grp_eng\\Shared\\ET Jobs\\C -CAD Drwg & Documtn\\EJ1898C - Autodesk Inventor Development\\Label WMF Outputer\\HDAL Logo - 21mm blackBorder.dwg" 1.0 1.0 1.0 0.0 ) ) ) (princ) ) Thanks heaps... Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted July 5, 2011 Share Posted July 5, 2011 It looks to be like this bit: ([b]vlax-method-applicable-p[/b] (setq object ([b]vlax-ename->vla-object eName[/b])) 'getboundingbox) is getting the bounding box of object 'eName' and saving it to 'object'... No, from the help: vlax-ename->vla-object Transforms an entity to a VLA-object 'eName' is an Entity Name, not a VLA-Object. The 'getboundingbox' method applies to a VLA-Object, not the entity name, so the selected selected must be converted to a VLA-Object before we can use this method. Then, again from the help: vlax-method-applicable-p Determines if an object supports a particular method So, that line of code is checking that the VLA-Object form of the selected Entity supports the getboundingbox method. For guidance on how to access the help for these functions, read this tutorial. Quote Link to comment Share on other sites More sharing options...
Hickoz_bro Posted July 5, 2011 Author Share Posted July 5, 2011 Thanks Lee, yeah, i found the LISP Reference guide on your site just after I posted that last post. That tutorial looks quite handy too... My problem though is that I don't know what function to look for... Thanks again. Quote Link to comment Share on other sites More sharing options...
BlackBox Posted July 5, 2011 Share Posted July 5, 2011 My problem though is that I don't know what function to look for... One of my favorite tools in VLIDE, especially when I first started developing with vla-* functions, is the Apropos. :wink: Quote Link to comment Share on other sites More sharing options...
Hickoz_bro Posted July 6, 2011 Author Share Posted July 6, 2011 Okay... I found it... Not quite sure what it does, but I found the help file, so I'll start there next time I'm LISPing... Cheers Quote Link to comment Share on other sites More sharing options...
BlackBox Posted July 6, 2011 Share Posted July 6, 2011 Okay... I found it... Not quite sure what it does, but I found the help file, so I'll start there next time I'm LISPing... Cheers One small example... in VLIDE, open a new file, and type "vla-" ( 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.