Community
Civil 3D Forum
Welcome to Autodesk’s Civil 3D Forums. Share your knowledge, ask questions, and explore popular AutoCAD Civil 3D topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to select lines and add label on line or curve with macro,script or Lisp

17 REPLIES 17
SOLVED
Reply
Message 1 of 18
Anonymous
2352 Views, 17 Replies

How to select lines and add label on line or curve with macro,script or Lisp

Hi, I was wondering is there anyway We can type and select the different lines with layer name and add a label with different line label style with civil 3D or no ? For example : select house line and add label with distance only and then select lot lines add label with bearing and distance on those lines.

17 REPLIES 17
Message 2 of 18
tcorey
in reply to: Anonymous

See the code:

 

(defun c:go(/ lay ss len ctr ob pt)

  (vl-load-com)

  (setq lay (cdr (assoc 8 (entget (car (entsel "\nSelect object on layer: "))))))

  (setq ss (ssget "x" (list (cons 8 lay)))
	len (sslength ss)
	ctr 0)

  (while (< ctr len)
    (setq ob (ssname ss ctr))
    (if (= (cdr (assoc 0 (entget ob))) "LWPOLYLINE")
      (progn
      (setq pt (cdr (assoc 10 (entget ob))))
      (vl-cmdf "addsegmentlabels" pt "")
      )
      )
    (setq ctr (1+ ctr))
    )
  (princ)
  );end defun

This is written for lwpolyline objects, but can be changed for lines, arcs, etc.

 

 

Open the Add Label dialog and set your label style. No need to press Add, just run the routine after setting the style on the dialog.

 

I created a screencast to show it working, but the upload is taking forever. I will attach it here in the morning.



Tim Corey
MicroCAD Training and Consulting, Inc.
Redding, CA
Autodesk Gold Reseller

New knowledge is the most valuable commodity on earth. -- Kurt Vonnegut
Message 3 of 18
tcorey
in reply to: Anonymous

 



Tim Corey
MicroCAD Training and Consulting, Inc.
Redding, CA
Autodesk Gold Reseller

New knowledge is the most valuable commodity on earth. -- Kurt Vonnegut
Message 4 of 18
Anonymous
in reply to: tcorey

Hi Tcorey, Thank you so much for your help. But I was looking for something to write instead of opening the dialog box for add label in civil 3D. That would be awesome if you can write something for us to select label style then select the lines for annotating with the same layers. 

 

Thank you so much.

Message 5 of 18
Anonymous
in reply to: tcorey

Tim,

 

This is exactly what I was looking for, though it seems to only label certain polylines on the layer, not all. Is there anything in the code that prevents this?

Message 6 of 18
tcorey
in reply to: Anonymous

I think I have it fixed.

 

The Civil 3D addsegmentlabels function requires a point as input, rather than a selection set. That means that some of the points I was sending to the function we at places where there was more than one object, so the wrong object was being selected. The way I fixed it is pretty crude, I suspect. What I did was use HideObjects to make sure the polyline that is currently to be labeled is isolated from the rest of the selection set. 

 

I tested with a smallish selection set, but I can imagine you might see some flashing on the screen when working with large selection sets. Let me know.

 

Also, addressing those of you who are real programmers, how would you handle this? I mean, rather than using hideobjects.

 

Here's the revised code:

 

(defun c:go(/ lay ss len ctr ob pt ss2) 

  (vl-load-com)
  (setq lay (cdr (assoc 8 (entget (car (entsel "\nSelect object on layer: "))))))
  (setq ss (ssget "x" (list (cons 8 lay)))
	len (sslength ss)
	ctr 0)
  (while (< ctr len)
    (setq ob (ssname ss ctr))
    (if (= (cdr (assoc 0 (entget ob))) "LWPOLYLINE")
      (progn
	(setq ss2 (ssget "x" (list (cons 8 lay))))
	(ssdel ob ss2)
	(vl-cmdf "hideobjects" ss2 "")	
      (setq pt (cdr (assoc 10 (entget ob))))      
      (vl-cmdf "addsegmentlabels" pt "")
	(vl-cmdf "UNISOLATEOBJECTS")      
      )
      )
    (setq ctr (1+ ctr))
    )
  (princ)
  );end defun

 

 



Tim Corey
MicroCAD Training and Consulting, Inc.
Redding, CA
Autodesk Gold Reseller

New knowledge is the most valuable commodity on earth. -- Kurt Vonnegut
Message 7 of 18
Anonymous
in reply to: tcorey

Thanks for the revision. It applies to more objects now, and I did see some flashing as it was applying to the few hundred polylines I've got in my drawing. However, it also applies to different layers, and I'm just trying to label all polylines on one layer with the same label style.

 

Also, it seems to have done the following:

  1. Removed/hid certain components of my label (I have 2 text components, Bearing & Distance, and it hid the distance component)
  2. When you click on the new labels, my properties dialog doesn't read that I've got a label selected.
Message 8 of 18
tcorey
in reply to: Anonymous

Clayton, can you either post a drawing or send one directly to me: tcorey at shasta dotcom.

 

The other objects must be getting selected because they aren't being hidden. I hate to have to hide the entire drawing, especially if it's large. Would it be too big a deal if I isolate the layer you have selected and then un-isolate it at the end of the routine?

 

Tim

 



Tim Corey
MicroCAD Training and Consulting, Inc.
Redding, CA
Autodesk Gold Reseller

New knowledge is the most valuable commodity on earth. -- Kurt Vonnegut
Message 9 of 18
Anonymous
in reply to: tcorey

Tim

 

Very useful lisp indeed. Is there a way to tailor it to do single line segments as well? "ie in subdivision lot lines" I took your code and changed it to "line" it does the same thing as Clayton described. It labels some, and on some it triple labels. Your help and advice is greatly appreciated.

 

Thank you.

Message 10 of 18
tcorey
in reply to: Anonymous


@Anonymous wrote:

Tim

 

Very useful lisp indeed. ...


Potentially useful. Once I get the kinks worked out, then we can call it useful. 😉

 

Regarding getting it to also work on lines, yes, you can change the line:

 

(if (= (cdr (assoc 0 (entget ob))) "LWPOLYLINE")

 

to read:

 

(if (or (= (cdr (assoc 0 (entget ob))) "LWPOLYLINE") (= (cdr (assoc 0 (entget ob))) "LINE"))

 

That will pick up lines and lwpolylines.

 

This routine is nowhere near sophisticated enough to eliminate the duplicate labels caused by overlapping segments.

 

Once Clayton, or someone, provides a file that I can use to test more rigorously, I will attempt to put the finishing touches on this. I invite help from anyone else here who wants to give it a go. 

 

 



Tim Corey
MicroCAD Training and Consulting, Inc.
Redding, CA
Autodesk Gold Reseller

New knowledge is the most valuable commodity on earth. -- Kurt Vonnegut
Message 11 of 18
tcorey
in reply to: Anonymous

Well, the way I was doing it, using object isolation, is working, but when try to do it on the file you sent it takes forever. It processed thirty-five lines, of 1948, in four minutes. You could do it faster by hand.

 

SSget function has a :E filter that will find all objects that are within the pickbox. I will utilize that, test, and post a new version for y'all. Stay tuned...



Tim Corey
MicroCAD Training and Consulting, Inc.
Redding, CA
Autodesk Gold Reseller

New knowledge is the most valuable commodity on earth. -- Kurt Vonnegut
Message 12 of 18
Anonymous
in reply to: tcorey

Thank you for all your help.

Message 13 of 18
tcorey
in reply to: Anonymous

Here's the latest. It works almost perfectly, but still finds the wrong object occasionally. I am at my wit's end as to how to make it select the object I want, without using object isolation, which takes way too long on larger drawings. Let me know how this works for you:

 

(defun c:go ( / lay ss len ctr ob pt ss2 ctr1 len1 obs obtyp p1 vertices thelist n x1 y1 x2 y2 p2 ccmdecho cpickbox )
  (vl-load-com)
  (setq ccmdecho (getvar "CMDECHO"))
  (setvar "CMDECHO" 0)  
  (setq lay (cdr (assoc 8 (entget (car (entsel "\nSelect object on layer: "))))))
  (setq cpickbox (getvar "PICKBOX"))
  (setvar "PICKBOX" 1)
  (setq ss (ssget "x" (list (cons 8 lay)))
	len (sslength ss)
	ctr 0)  
  (prompt "\nProcessing....")
  (vl-cmdf "zoom" "O" ss "")
  (while (< ctr len)
    (setq ob (ssname ss ctr))
    (setq obtyp (cdr (assoc 0 (entget ob))))    
   ;if it's an lwpolyline 
    (if (= obtyp "LWPOLYLINE")
      (progn
       (setq pl (vlax-ename->vla-object ob))
       (setq vertices (vlax-get-property pl 'Coordinates))
       (setq thelist (vlax-safearray->list  (variant-value vertices)))
       (setq n 0)
       (setq x1 (rtos (nth n thelist)))
       (setq n (1+ n))
       (setq y1 (rtos (nth n thelist)))
       (setq n (1+ n))
       (setq x2 (rtos (nth n thelist)))
       (setq n (1+ n))
       (setq y2 (rtos (nth n thelist)))
       (setq p1 (list (atof x1) (atof y1))
	     p2 (list (atof x2) (atof y2))
	     pt (polar p1 (angle p1 p2) (/ (distance p1 p2) 6.2343))
	     )
       (vl-cmdf "addsegmentlabels" pt "")
       (prompt (strcat "\n" (rtos (1+ ctr) 2 0) " objects processed, of " (rtos len 2 0) " total."))
       );end progn
    );end if
       

;if it's a line
    (if (= obtyp "LINE")
      (progn
      (setq p1 (cdr (assoc 10 (entget ob)))
	    p2 (cdr (assoc 11 (entget ob)))
	    pt (polar p1 (angle p1 p2) (/ (distance p1 p2) 3.1243))
	    )
      (vl-cmdf "addsegmentlabels" pt "")
       (prompt (strcat "\n" (rtos (1+ ctr) 2 0) " objects processed, of " (rtos len 2 0) " total."))
      );end progn
      );end if
     (setq ctr (1+ ctr))
    );end while
    
  
  (vl-cmdf "regen")
  (setvar "CMDECHO" ccmdecho)
  (setvar "PICKBOX" cpickbox)
  (princ)
  );end defun


Tim Corey
MicroCAD Training and Consulting, Inc.
Redding, CA
Autodesk Gold Reseller

New knowledge is the most valuable commodity on earth. -- Kurt Vonnegut
Message 14 of 18
Anonymous
in reply to: tcorey

Tim

Try this one. It work on doing multiple up to at least 40 to 50 at a time. Without isolating. Let me know if it works for you.

 

(PRINC "\n LAL: Label All Lines")
(VL-LOAD-COM)
(DEFUN C:LAL ( / ax-ptmid LAY SS:LINES CNT EN EN1 PT A)
(command-s "undo" "BEgin")

    ;;returns the midpoint
    (defun ax-ptmid  (objcurva)
        (vlax-curve-getPointAtDist
            objcurva
        (/ (vlax-curve-getdistatparam objcurva(vlax-curve-getendparam objcurva)) 2))
    )

    (if(SETQ SS:LINES (SSGET'((0 . "LINE,ARC,LWPOLYLINE,POLYLINE"))))
        (progn
            (SETQ CNT 0)
            (REPEAT (SSLENGTH SS:LINES)
                (SETQ EN (SSNAME SS:LINES CNT)
                      EN1 (VLAX-ENAME->VLA-OBJECT EN)
                      LAY (VLAX-GET EN1 'LAYER)
                      PT (ax-ptmid EN1)
                )
                (vl-cmdf "ADDSEGMENTLABELS" "NEA" PT "")
                (SETQ CNT (+ 1 CNT))
            )
        );progn
    );if SETQ SS:LINES
    (command-s "undo" "End")
    (PRINC)
)

Message 15 of 18
rl_jackson
in reply to: Anonymous

Not discrediting anything that @tcorey and @Anonymous did in regards to the lisp routine, as I'm sure it would be quite useful.

 

But based on the OP original post, wouldn't not be easier just to turn all the houses in to Parcels with a parcel line label that displayed distance. Its fairly automated and would accomplish the same goal in seconds.

 

I believe the same would hold true for the Lot lines as well, its a subdivision, so Parcels are definitely the way to go when doing that type of work in C3D.


Rick Jackson
Survey CAD Technician VI

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature

Message 16 of 18
Anonymous
in reply to: rl_jackson

I was looking for a way to label each individual lot line in a subdivision. Which the issue i had with running parcels is when turning them off to avoid double lines in the file. The dimensions turn off with them. Ive also had a ton of issues with mapchecks in the civil 3d.  

Message 17 of 18
rl_jackson
in reply to: Anonymous

"double lines"

 

Sounds to me, that when your converting the lines and arcs to Parcels you not having it erase the object you used to create the parcels. There should be no doubles if you do that.

 

As far as the Labels go. That sounds like a style thing or ambient setting issue. I use what is called the Layer 0 method. This puts all objects on Layer 0 and then within the style I make the object appear on a certain layer.

 

Mapchecks are built into parcels, that's the nice thing about them and you can quickly get a report for all Parcels via the Toolbox - Reports Manager - Parcels  - Parcel Map Check Report.


Rick Jackson
Survey CAD Technician VI

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature

Message 18 of 18
wadewbaker
in reply to: tcorey

Good morning Tim, (@tcorey)

I'm using the code you posted on 3/7/17 at 8:56 am.
How do I edit the code to also pic arcs?
I have no coding experience.

Thanks.

Tags (1)

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

Post to forums  

Rail Community


 

Autodesk Design & Make Report