Jump to content

Adding Geometry with Lisp


Hickoz_bro

Recommended Posts

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 .:x

Link to comment
Share on other sites

  • Replies 34
  • Created
  • Last Reply

Top Posters In This Topic

  • Hickoz_bro

    15

  • Lee Mac

    10

  • Tharwat

    8

  • BlackBox

    2

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.

Link to comment
Share on other sites

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...

Link to comment
Share on other sites

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 :)

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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...

Link to comment
Share on other sites

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).

Link to comment
Share on other sites

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...

Link to comment
Share on other sites

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...

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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:

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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-" (

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...