Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Draw multiple circles using a point selection set

21 REPLIES 21
Reply
Message 1 of 22
rgarcia79
9294 Views, 21 Replies

Draw multiple circles using a point selection set

Hello,

I'm trying to create my first lisp routine but I am having some issues.

I'm using autoCAD Civil 3D 2011 and I can't seem to run my command although I've loaded it.

I'm selecting cogo points that I've added to a profile view (not sure if that makes a difference), but as a workaround all I want to do is create 0.5 r circles in place of those points so that I can carry the points over to 2004.

Here is my poor attempt at creating a LISP.

 

(defun C:TEST1 ()
(setq points (ssget("point"))
(command "circle" points r 0.5))

 

Any tips or tricks would be definitely welcome,

Thanks,

Richard

21 REPLIES 21
Message 2 of 22
Shneuph
in reply to: rgarcia79


@rgarcia79 wrote:

 

(defun C:TEST1 ()
(setq points (ssget("point"))
(command "circle" points r 0.5))

 


Hi Richard,

 

Your code is a long way from working but here are some tips to get you started since you're just beginning:

 

(Defun C:Test1 (/ POINTS)

Local variables that you use w/ (setq etc. go here (after the / ).  They then will be removed from memory after the program runs.

 

Try this when you make your selection set.  I don't have Cogo points so I don't know what to use but you can figure it out.

(entget (car (entsel)));   This is golden.. Paste it into your command line and select one of the cogo points and look for group code (0 . "COGO_Point") That tells you what the object type is.  I'm betting it's not actually "COGO_POINT" but you can find it and that's what you want to use here..

 

(setq points (ssget '((0 . "COGO_POINT"))))

This is how you construct the selection set filter.  "COGO_POINT" (which remember probably isn't correct) is case sensitive (I believe)


Then you have a selection set with many cogopoints in your "POINTS" variable.

You have to somehow iterate through all of them to draw the circles one for each point

You can convert a selectionseet to an entity list like this.. (others on this forum probably have more efficient ways..)

 

(setq n 0)

(while (setq cent (ssname points n))

  (setq PointsList (append Pointslist (list cent)))

  (setq n (1+ n))

);while

 

Then you can use a loop to cycle through the entity names

(foreach Entity Pointslist;  This means foreach ename that you assign to variable entity in the pointslist list

  (extract the point location);  You have to get the pointlocation from the entity list (assign to pointlocation)

  (command "circle" pointlocation 0.5)

);foreach

 

Here is the code to do it with a regular AutoCAD Point.. you need to change "POINT" to "COGO_POINT" (or whatever it is) and make sure you can extract the location in the same manner..

 

(Defun C:TEST1 (/ SSpoints n cent PointsList PointLocation)
  (setq SSpoints (ssget '((0 . "POINT"))))
  (setq n 0)
  (while (setq cent (ssname sspoints n))
    (setq PointsList (append Pointslist (list cent)))
    (setq n (1+ n))
    );while
  (foreach Point PointsList
    (setq PointLocation (cdr (assoc 10 (entget point))))
    (command ".circle" PointLocation 0.5)
    );foreach
  (princ)
  );defun

 

---sig---------------------------------------
'(83 104 110 101 117 112 104 64 71 109 97 105 108 46 99 111 109)
Message 3 of 22
Kent1Cooper
in reply to: Shneuph


@Shneuph wrote:

.... (others on this forum probably have more efficient ways..)....

 

Here is the code to do it with a regular AutoCAD Point.. you need to change "POINT" to "COGO_POINT" (or whatever it is) and make sure you can extract the location in the same manner..

 

(Defun C:TEST1 (/ SSpoints n cent PointsList PointLocation)
  (setq SSpoints (ssget '((0 . "POINT"))))
  (setq n 0)
  (while (setq cent (ssname sspoints n))
    (setq PointsList (append Pointslist (list cent)))
    (setq n (1+ n))
    );while
  (foreach Point PointsList
    (setq PointLocation (cdr (assoc 10 (entget point))))
    (command ".circle" PointLocation 0.5)
    );foreach
  (princ)
  );defun

One slightly more efficient way would be to make the Circles directly from the selection set, rather than to convert that into a list first.  One way:

 

(Defun C:TEST2 (/ SSpoints)
  (setq SSpoints (ssget '((0 . "POINT"))))
  (repeat (sslength SSpoints)
    (command

      "_.circle"

      (cdr (assoc 10 (entget (ssname SSpoints 0)))); center

      0.5 ; radius

    ); command
    (ssdel (ssname SSpoints 0) SSpoints)

  ); repeat

  (princ)
);defun

 

Or, if there are really large numbers of them, you might actually notice the time savings from using (entmake) instead of (command):
 

(Defun C:TEST3 (/ SSpoints)
  (setq SSpoints (ssget '((0 . "POINT"))))
  (repeat (sslength SSpoints)
    (entmake

      (list

        '(0 . "CIRCLE")

        (cons 10 (cdr (assoc 10 (entget (ssname SSpoints 0))))); center

        '(40 . 0.5); radius

      ); list

    ); entmake
    (ssdel (ssname SSpoints 0) SSpoints)

  ); repeat

  (princ)
);defun

Kent Cooper, AIA
Message 4 of 22
Anonymous
in reply to: Kent1Cooper

Kent, I saw Richard's post on the Civil3D forum and posted a fix there for him, but he brings up a ? for me.  I struggle a little bit in extracting sub entities, I just don't do this enough to remember how I did it last time.  It takes me a while to get what I need.  I list (command) the AECC point and get the following:

 

Select objects:

                  AECC_COGO_POINT  Layer: "V-NODE"
                            Space: Model space
                   Handle = 6b93
Primary point group : Topo
       Point Number : 5018
           Northing : 3657212.9580'
            Easting : 11790572.8300'
    Point Elevation :
    Raw Description : PLAT
   Full Description : PLAT
       Survey Point : False

 

Now when I get to the list data thru lisp, I struggle to get out what I need.  Here is the entget data.

 

Command: (setq hrhl (entget hrh))
((-1 . <Entity name: 7eee3618>) (0 . "AECC_COGO_POINT") (330 . <Entity name:
7eecdcf8>) (5 . "6B93") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 .
"V-NODE") (100 . "AeccDbCogoPoint"))

Command:

 

What is the easiest way to extract the point number, northing, easting, point elevation and raw description?

Message 5 of 22
Kent1Cooper
in reply to: Anonymous


@Anonymous wrote:

.....  I struggle a little bit in extracting sub entities, I just don't do this enough to remember how I did it last time. ....

 

Now when I get to the list data thru lisp, I struggle to get out what I need.  Here is the entget data.

 

Command: (setq hrhl (entget hrh))
((-1 . <Entity name: 7eee3618>) (0 . "AECC_COGO_POINT") (330 . <Entity name:
7eecdcf8>) (5 . "6B93") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8 .
"V-NODE") (100 . "AeccDbCogoPoint"))

Command:

 

What is the easiest way to extract the point number, northing, easting, point elevation and raw description?


Like Schneuph whose message I was replying to, my suggestion is about regular AutoCAD Point entities -- I don't have COGO points.  It could be that what you want exists as sub-entities, similar to the vertices of "heavy" Polylines or Attributes in Block insertions.  Try this:

 

(setq ent hrh)

(entget (setq ent (entnext ent)))

 

and repeat that second line several times, to see what you get.  If you get entity data lists for a Point and some Text or something, you can extract values from those.

 

Or, it could be that the 330-code Entity Name contains what you want, or part of it.  Try this:
 

(entget (cdr (assoc 330 hrhl)))
 

and see what you get.  It may have further entity-name entries nested within it, so you may need to dig deeper into those.

 

Or, they could be in Extended Data.  Try this:

 

(cadr (assoc -3 (entget hrh '("ACAD"))))

 

with whatever is appropriate as an application name in place of the "ACAD" there, if necessary [that, I couldn't tell you].

Kent Cooper, AIA
Message 6 of 22
Anonymous
in reply to: Kent1Cooper

Thank you, Will do.

Message 7 of 22
Shneuph
in reply to: Kent1Cooper


@Kent1Cooper wrote:

 

Or, they could be in Extended Data.  Try this:

 

(cadr (assoc -3 (entget hrh '("ACAD"))))

 

with whatever is appropriate as an application name in place of the "ACAD" there, if necessary [that, I couldn't tell you].


Kent,

  Do you know ANY other applications that could be put in place of "ACAD"?  I wonder sometimes if there is Xdata on objects from applications that I just don't know the name of.  I don't know how to tell what applications may have added xdata to put in ACAD's place.  Any suggestions?

---sig---------------------------------------
'(83 104 110 101 117 112 104 64 71 109 97 105 108 46 99 111 109)
Message 8 of 22
Kent1Cooper
in reply to: Shneuph


Shneuph wrote:

 

Kent,

  Do you know ANY other applications that could be put in place of "ACAD"?  I wonder sometimes if there is Xdata on objects from applications that I just don't know the name of.  I don't know how to tell what applications may have added xdata to put in ACAD's place.  Any suggestions?


I don't know of any, in particular, but they certainly allow for the possibility, if you read about things like "Retrieval of Extended Data" in the AutoLISP Developer's Guide.  I couldn't say whether some AutoCAD overlay programs like Civil3D might have their own application names that should go into an (entget) function looking for Extended Data.

Kent Cooper, AIA
Message 9 of 22
rgarcia79
in reply to: Kent1Cooper

Thanks Kent, Sig, and azrdgldr ,

Looks like I am way over my head with these lisp commands.

I'm embarressed to say that I can't even copy the lisp and load the application in AutoCAD.

I've copied and pasted one of the lisps just to try it out and I've saved it as cogo.lsp.

I then went to Manage>Load Application> and double clicked on cogo.lsp

But as soon as I type cogo in the command line it says unknown command.

I though I've followed all the right steps.

Also I have attached the cogo's in the profile view.

 

I guess it's not that easy to jump right into something,

Thanks a bunch,

 

Richard

Message 10 of 22
rgarcia79
in reply to: rgarcia79

Ok now I know why I couldn't run my commands. I will test each one and let you guys know what works for these cogo points. Thanks for the quick tutorial and hopefully something will work.

Message 11 of 22
stevesfr
in reply to: Kent1Cooper

Kent:  I know if I change "POINT" TO "INSERT"  I can get the program to ask me to select a block or several, but how to hardwire a certain block name into the program, or prompt me for the block name and hit them all with a circle at their respective insertion points?

Stumped, TIA

Steve

Message 12 of 22
rgarcia79
in reply to: Kent1Cooper

Hi Kent,

What if simply did not select a filter. That's the only way I could select my entities but unfortunately I get an error.

 

Here is the code.

 

(Defun C:TEST3 (/ SSpoints)
  (setq SSpoints (ssget '()))
  (repeat (sslength SSpoints)
    (entmake
      (list
        '(0 . "CIRCLE")
        (cons 10 (cdr (assoc 10 (entget (ssname SSpoints 0))))); center
        '(40 . 0.5); radius
      ); list
    ); entmake
    (ssdel (ssname SSpoints 0) SSpoints)
  ); repeat
  (princ)
);defun

 

This is the error:

Select objects:  ; error: bad DXF group: (10)

 

Would eliminating the filter group help in any way?

Message 13 of 22
Kent1Cooper
in reply to: stevesfr


@stevesfr wrote:

Kent:  I know if I change "POINT" TO "INSERT"  I can get the program to ask me to select a block or several, but how to hardwire a certain block name into the program, or prompt me for the block name and hit them all with a circle at their respective insertion points?

....


Add an "X" option for find-in-the-whole-drawing selection, rather than User selection.  A Block's name is in the 2-code entry, so you should be able to do:

 

(setq SSblocks (ssget "X" '((2 . "YourBlockName"))))

 

[Some would include the (0 . "INSERT") in there for the entity type:

 

(setq SSblocks (ssget "X" '((0 . "INSERT") (2 . "YourBlockName"))))

 

but that's really not necessary unless you might have some other entity type with a "name" that might be the same that of the Block.]

 

With that as the selection line, I think Test2 or Test3 [adjusting the radius if needed, etc.] should do what you're looking for.

 

EDIT:  To be prompted for a Block name, try something like this [untested]:

 

(Defun C:TEST2 (/ SSblocks)

  (setq

    blkname (getstring "\nBlock name: ")
    SSblocks (ssget "X" (list (cons 2 blkname)))

  )
  (repeat (sslength SSblocks)
    (command

      "_.circle"

      (cdr (assoc 10 (entget (ssname SSblocks 0)))); center

      0.5 ; radius

    ); command
    (ssdel (ssname SSblocks 0) SSblocks)

  ); repeat

  (princ)
);defun

Kent Cooper, AIA
Message 14 of 22
Kent1Cooper
in reply to: rgarcia79


@rgarcia79 wrote:

Hi Kent,

What if simply did not select a filter. That's the only way I could select my entities but unfortunately I get an error.

.... 

(Defun C:TEST3 (/ SSpoints)
  (setq SSpoints (ssget '()))
....

        (cons 10 (cdr (assoc 10 (entget (ssname SSpoints 0))))); center
....

 

This is the error:

Select objects:  ; error: bad DXF group: (10)

 

Would eliminating the filter group help in any way?


I haven't seen (ssget) functions with empty filter lists like that before, but I tried it, and that in itself doesn't seem to cause any problem.  Usually one would just do this for a non-filtered User selection:

 

(setq whatever (ssget))

 

But if you're picking COGO points that way, their entity data as posted in your earlier message doesn't include a 10-code entry, which is probably the source of the error message, when it tries to extract one to use as the center of a Circle.  You would need to find something in the sub-entities or Extended Data or wherever it is, that is an XYZ-components point -- look at the entity data for a Point entity, Circle, Arc, Block. Line, Text, or certain other things, all of which have insertion or center or start point entries formatted like (10 X-coord Y-coord Z-coord).
 
While I'm here, I realized that [assuming you do find something with a 10-code to take for the center of the Circle] the (cons) line above [in the (entmake) in TEST3, not in TEST2 using (command)] could be reduced to just:

 

        (assoc 10 (entget (ssname SSpoints 0))); center

 

As I had it, it was putting a 10 on the front of a list from which it had just removed the 10 from the front, which is a waste of effort -- it should just take the 10-code entry straight.

Kent Cooper, AIA
Message 15 of 22
rgarcia79
in reply to: Kent1Cooper

Thanks Kent,

I found that test 2 and 3 worked perfectly with points so all I need to find out is the group name for filtering cogo points as you guys have stated earlier.

I'll still slosh along and muddle my way through.

I'll post when I find the solution.

Thanks, I can feel I'm almost there.

 

Richard

Message 16 of 22
Kent1Cooper
in reply to: rgarcia79


@rgarcia79 wrote:

....all I need to find out is the group name for filtering cogo points.....


The group name for filtering them should be the (0 . "AECC_COGO_POINT") in what (entget) reported in your earlier post.  The trick is going to be finding the subentity [or whatever] for each one, that contains some kind of insertion point information.

Kent Cooper, AIA
Message 17 of 22
rgarcia79
in reply to: Kent1Cooper

Yes, that worked! At least in selecting the entities. No 10 code but there is a northing and easting which would be equivalent to xy coordinates.

Not quite sure how this 10 code works but I'm assuming these coordinates would be under a different code?

Not quite sure where to look.

Only one more command, almost there.

Message 18 of 22
Kent1Cooper
in reply to: rgarcia79


@rgarcia79 wrote:

.... No 10 code but there is a northing and easting which would be equivalent to xy coordinates.

Not quite sure how this 10 code works but I'm assuming these coordinates would be under a different code?

Not quite sure where to look.

....


Go back to my second message, that talks about some possibilities -- sub-entities, 330 entity names, extended data.  For all I know there are other possibilities, too.  I don't have COGO points, but maybe if you post a drawing, I can at least see whether I can look at them, even if I can't generate them.

Kent Cooper, AIA
Message 19 of 22
Anonymous
in reply to: Kent1Cooper

Posting a drawing won't help in this situation since you are not using Civil3D.  If you export the drawing the entites change so you are not dealing with the same object per say.  Civil3D is a different ball of wax.  They group their objects and it takes about 2-4 explodes to get it to explode like a typical explode in AutoCAD.  If you look at the drawing in this post it will show you how an AeCC Cogo Point is changed when it is exported to a different format.  Hence me struggling to extract data from a Cogo Point.

 

http://forums.autodesk.com/t5/Visual-LISP-AutoLISP-and-General/U-blocks-to-Ascii-point-file/td-p/309...

Message 20 of 22
arcangel1001
in reply to: Shneuph

Mr. Kooper,

    

I am trying to modify your code to do the following:

 

1) make a selection set of circles via window

2) make a list of their centerpoints

3) draw a line from center to center to center (color not important)

 

It tried to modify your lisp code but i do not understand how to loop through the points.

 

the line command makes a line from center of each circle to 0,0,0. But instead of 0,0,0 i've tried

(setq pointlocation2 (+ 1 pointlocation) and adding pointlocation2 to the variables.

 

I've learned alot about lisp just trying to understand your piece of code, but for me, looping is still difficult.

Please help.

(Defun C:TEST1 (/ SSpoints n cent PointsList PointLocation)
  (setq SSpoints (ssget '((0 . "CIRCLE"))))
  (setq n 0)
  (while (setq cent (ssname sspoints n))
    (setq PointsList (append Pointslist (list cent)))
    (setq n (1+ n))
    );while
  (foreach Point PointsList
    (setq PointLocation (cdr (assoc 10 (entget point))))
    (command ".LINE" PointLocation "0,0,0" "")
    );foreach
  (princ)
  );defun

 

Untitled.png

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost