Jump to content

Adding Geometry with Lisp


Hickoz_bro

Recommended Posts

Gents,

 

It's knock off time here, and I've spent the past few hours trying to figure out how to add a point to my drawing at the bounding box extents of an object.

 

This is what I've got so far. Few things to note. I'm looking for the lower right corner of my bounding box, hence the co-ordinates.

 

This is my first such endeavor (inserting geometry with VLA), so I've *******ized someone else's code, in the original code, they put a rectangle around the object using the lower left and upper right corner. I'm satisfied that I've got the co-ordinates part of it right, I think I've just got the wrong syntax for the point insertion. I've tried vla-addpoint (Point) method, but that didn't work.

 

Any help would be greatly appreciated...

 

(defun c:BNDBX (/ eName my mx)
 (vl-load-com)
(if (setq eName (car (entsel "\n  >>  Select Object  >> ")))
 (progn
(vla-getboundingbox (vlax-ename->vla-object eName) 'my 'mx)

(vla-cmdf "._point"
  (list	(car (vlax-safearray->list mx))
	(cadr (vlax-safearray->list my))

  )
)
)
)
   (princ)
     )

 

Thanks in advance.

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

Check this out ... :)

 

(defun c:BNDBX (/ eName my mx)
 (vl-load-com)
 (if (setq eName (car (entsel "\n  >>  Select Object  >> ")))
   (progn
     (vla-getboundingbox (vlax-ename->vla-object eName) 'my 'mx)
     (vl-cmdf "_.POINT" "_non" (vlax-safearray->list my))
     (vl-cmdf "_.POINT" "_non" (vlax-safearray->list mx))
   )
   (princ)
 )
 (princ)
)

Tharwat

Link to comment
Share on other sites

That looks like it'll put 2 points in (if I've understood your code)? one at point 'my' and one at 'mx'...

 

What I'm trying to do is put 1 point, at the x-cordinate of 'mx' and the y-cordinate of 'my' so as to get the lower right hand corner of the bounding box.

Link to comment
Share on other sites

Like this .... ? :)

 

(defun c:BNDBX (/ eName my mx)
 ;; Tharwat 03. 07. 2011
 (vl-load-com)
 (if (setq eName (car (entsel "\n  >>  Select Object  >> ")))
   (progn
     (vla-getboundingbox (vlax-ename->vla-object eName) 'my 'mx)
     (vl-cmdf "_.POINT"
              "_non"
              (list (car (vlax-safearray->list mx))
                    (cadr (vlax-safearray->list my))
              )
     )
   )
   (princ)
 )
 (princ)
)

 

Tharwat

Link to comment
Share on other sites

Looks good... I'll try it at work tomorrow morning.

 

Looks like the only change you've made is adding in the "_non" bit... What is that for? And I just spotted you've changed it from vlA-cmdf to vl-cmdf... Can you explain this one for me?

Do you know if there's any reason to do it like you've suggested vl-cmdf "_.POINT" instead of vla-addpoint? Are there pro's and con's or is it 6 of one...

 

Sorry for the questions, Just starting to understand this stuff...

Link to comment
Share on other sites

First "_non" would ignore any osnap settings which would put our entity (point) in its exact location . things like turning off the osnap .

Secondly the vla-cmdf is written wrong and it should be as I did write it like this vl-cmdf .

Finally ,both vl-cmdf and vla-addpoint are the same in result , but the vla-addpoint is much faster and powerful because the vl-cmdf is like commnad call in Autocad .

 

Try it with vla-addpoint and if you stock just shout and we will correct any mistake if you may have . :)

 

Regards.

 

Tharwat

Link to comment
Share on other sites

Do you know if there's any reason to do it like you've suggested vl-cmdf "_.POINT" instead of vla-addpoint? Are there pro's and con's or is it 6 of one...

 

vl-cmdf is an alternative to using the command function, however, vl-cmdf will evaluate the validity of the supplied arguments before submitting the command to AutoCAD. Furthermore vl-cmdf will return T or nil depending upon whether the command was evaluated successfully.

 

vla-addpoint is a method of a VLA Block Object (including the Modelspace/Paperspace Collections which may also be viewed as Block Defintions). This method does not use the Point command in any way, and will modify the drawing database directly. vla-addpoint will return the VLA Point Object if successful.

Link to comment
Share on other sites

Okay guys... I thought I had this one under control.

 

I wanted to try the vla-addpoint method, but I just don't understand the syntax. I googled a bit, and found someone elses example, and I've modified it with my point data, but it still errors...

 

I think I understand what the syntax is doing, but I don't really understand the bit in bold... It appears to get the modelspace in which the point is inserted... I think???

 

      (vla-addpoint
[b]	(vla-get-ModelSpace
  (vla-get-activedocument (vlax-get-acad-object))
)[/b]
(list (car (vlax-safearray->list mx))
      (cadr (vlax-safearray->list my))
)
     )

Link to comment
Share on other sites

Since you are using the AddPoint method, you will need to supply the point list as a Variant of Safearray type. This may be constructed using such functions as vlax-make-variant, vlax-make-safearray, and vlax-safearray-fill; however, for 3D points, Visual LISP provides a convenient vlax-3D-point function for such purposes.

 

Consider its use in the following code:

 

([color=BLUE]defun[/color] c:test ( [color=BLUE]/[/color] activedocument activespace entity lowerleft object upperright )

 ([color=BLUE]setq[/color] activedocument ([color=BLUE]vla-get-activedocument[/color] ([color=BLUE]vlax-get-acad-object[/color]))
       activespace    ([color=BLUE]vlax-get-property[/color] activedocument ([color=BLUE]if[/color] ([color=BLUE]=[/color] 1 ([color=BLUE]getvar[/color] 'CVPORT)) 'Paperspace 'Modelspace))
 )  
 ([color=BLUE]if[/color]
   ([color=BLUE]and[/color]
     ([color=BLUE]setq[/color] entity ([color=BLUE]car[/color] ([color=BLUE]entsel[/color])))
     ([color=BLUE]vlax-method-applicable-p[/color] ([color=BLUE]setq[/color] object ([color=BLUE]vlax-ename->vla-object[/color] entity)) 'getboundingbox)
   )
   ([color=BLUE]progn[/color]
     ([color=BLUE]vla-getboundingbox[/color] object 'lowerleft 'upperright)
     ([color=BLUE]vla-addpoint[/color] activespace
       ([color=BLUE]vlax-3D-point[/color]
         ([color=BLUE]list[/color]
           ([color=BLUE]car[/color] ([color=BLUE]vlax-safearray->list[/color] upperright))
           ([color=BLUE]cadr[/color] ([color=BLUE]vlax-safearray->list[/color] lowerleft))
           0.0
         )
       )
     )
   )
 )
 ([color=BLUE]princ[/color])
)

For a short explanation surrounding the various ways to use the Visual LISP properties and methods, I would refer you to these threads:

http://www.cadtutor.net/forum/showthread.php?53374-xref-clip-boundry&p=361940&viewfull=1#post361940

 

http://www.cadtutor.net/forum/showpost.php?p=258403&postcount=9

 

Also, if you are not already doing so, I would strongly recommend that you use the Visual LISP IDE to write your programs, since the AutoLISP & Visual LISP Help Documentation may be accessed directly from within this IDE. A few tutorials on the topic may be found here.

Link to comment
Share on other sites

Thanks heaps for that Lee, I think I can see what's going on with that code sample... Those links you've provided are excellent too... I'm starting to understand how vla and vlax work...

 

Cheers

Link to comment
Share on other sites

You're welcome :)

 

It'll probably take some practice to get familiar with the AutoCAD Object Model and new data types introduced with Visual LISP, but the VLIDE Help Documentation is a great learning resource.

Link to comment
Share on other sites

Dammit... I thought I had it sorted... Something with this ssget is giving me grief...

 

It worked fine until I added in the '((0."Hatch")) filter... but I'm sure I've done that right...

 

	       (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)
	      )
	      '((0."HATCH"))
       )

 

Where have I gone wrong?

Link to comment
Share on other sites

Do it like this ...... :)

 

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

Tharwat

Link to comment
Share on other sites

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:

Link to comment
Share on other sites

Since that you can not add the filtration code to ssget "_c" we did as below :

 

1- used the ssget "_c" to select all entities that are within the two coordinate points .

2- I made a filtration to add to selection if the entity is HATCH .

3- At last I converted the number of hatch to the command line to see and to know how many Hatch entities that found within the selection Cross selection .

 

That's it .:)

 

Hope this make sense ?

 

Tharwat

Link to comment
Share on other sites

Where have I gone wrong?

 

You need an extra space:

 

'((0 . "HATCH"))

Since 0. is interpreted as a Real number (0.0), not a dotted pair.

 

Are you using the VLIDE to write your code? I say this because this mistake would be seen from the syntax highlighting that the VLIDE (or other code editors) offers.

Link to comment
Share on other sites

The code might be better written as:

 

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

Link to comment
Share on other sites

(setq lst (ssadd sset l))

 

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.

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