AutoLisp: Insert MTEXT at center inside polylined space

AutoLisp: Insert MTEXT at center inside polylined space

mnpatric
Enthusiast Enthusiast
3,453 Views
14 Replies
Message 1 of 15

AutoLisp: Insert MTEXT at center inside polylined space

mnpatric
Enthusiast
Enthusiast

I have the urgent need to program the AutoLisp automation to inset MTEXT at the center of each space that is enclosed with polyline.  Please help!  Thank you,

0 Likes
3,454 Views
14 Replies
Replies (14)
Message 2 of 15

Kent1Cooper
Consultant
Consultant

Have you tried Searching?  This kind of thing has come up before -- try Searching for terms such as "label Polyline areas" and similar wordings.

 

Also, much more information would be needed, if there isn't something already written that does what you need.  You don't say what you want the Mtext to say -- calculated area?  incrementing number?  User input for every one?  names of the seven dwarves?  etc.  It would also be necessary to know whether you would want to select the Polyline itself [or perhaps many at once?], or have a routine find all closed Polylines without User input, or pick inside the enclosed area(s), or some other approach, nor what would be needed about Style or size or justification or....  Check this out.

Kent Cooper, AIA
0 Likes
Message 3 of 15

mnpatric
Enthusiast
Enthusiast

Yes, there are some on the GOOGLE using the Visual Lisp, but I was wondering if there is simpler way with just plain AutoLisp.

 

I'm modifying the existing AutoLisp code that automatically place the MTEXT on drawings in the AutoCAD 2014.  I just need to find the way to find the center of a room that is drawn with polyline.  The contents of the MTEXT is retrieved from the database and formatted already.  Polylines are already selected in the code, and the mtext needs to be placed at the center of each polyline. No user input.  all Polylines should be closed, but occasionally open ones can be found.

 

Also, much more information would be needed, if there isn't something already written that does what you need.  You don't say what you want the Mtext to say -- calculated area?  incrementing number?  User input for every one?  names of the seven dwarves?  etc.  It would also be necessary to know whether you would want to select the Polyline itself [or perhaps many at once?], or have a routine find all closed Polylines without User input, or pick inside the enclosed area(s), or some other approach, nor what would be needed about Style or size or justification or....  Check this out.

0 Likes
Message 4 of 15

Kent1Cooper
Consultant
Consultant

@mnpatric wrote:

....  I just need to find the way to find the center of a room that is drawn with polyline.  ....


That's another thing you can almost certainly find with a little Searching.  Even that [as you will surely find in such a Search] requires more specificity.  There are different "center" locations -- center of bounding box?  centroid / "center of gravity"?  something else?  They may all be the same in a rectangular or otherwise biaxially symmetrical room, but will vary with irregular shapes, and the more irregular, the more they vary, for instance:

 

MiddleOfRoom.PNG

Kent Cooper, AIA
0 Likes
Message 5 of 15

mnpatric
Enthusiast
Enthusiast

As specified on my subject, I need to insert at the center "inside" enclosed space with polyline.  It is acceptable, if the insertion point is approximate center, but it must be inside the polylined space. 

0 Likes
Message 6 of 15

john.uhden
Mentor
Mentor

That reminds me of my program to label amoeba shaped polylines for SSURGO soil mapping.  It required iteration to be sure the point was inside the polyline, as there is no direct solution that I could find.

 

It's ugly, but I could copy and paste the applicable parts.

John F. Uhden

0 Likes
Message 7 of 15

Kent1Cooper
Consultant
Consultant

@mnpatric wrote:

....  It is acceptable, if the insertion point is approximate center, but it must be inside the polylined space. 


And therein lies part of the complexity of the problem, along with related issues [e.g. in your case, how far inside, affected by text size & justification, etc.].  When you find threads about this kind of thing, there will be considerable discussion, and various approaches suggested, about how to calculate a location that is guaranteed to be inside a given shape.  I'll leave the Searching to you -- it's all been brought up before.  When you find something that comes close to what you want to do, if it's not exactly what you want, bring it back here, and it can probably be fine-tuned for your needs.

Kent Cooper, AIA
0 Likes
Message 8 of 15

john.uhden
Mentor
Mentor

I redacted my SSURGO.lsp program to give you PLCENTROID.lsp (attached).

 

I through in a test command "PCTEST" for selecting polylines one by one and placing a point at the computed "centroid."

There's some extra baggage in it, but it won't hurt anything.  I think it's left over from my testing years ago.

 

My guess is that it will fail if the polyline isn't closed because it keeps looking for intersections of a ray and the polyline boundary.  I dunno; just try it out.

If it works for you, remember to entdel the ray when you exit, plus localize all those functions and symbols.

John F. Uhden

0 Likes
Message 9 of 15

mnpatric
Enthusiast
Enthusiast

thank you

0 Likes
Message 10 of 15

john.uhden
Mentor
Mentor

Thinking about building a better mouse trap, it might be better to increment a y value and intersecting a horizontal xline to get the maximum width and then making the x value the midpoint of same.  Can you do it, or do you want one of us to give it a shot?

John F. Uhden

0 Likes
Message 11 of 15

hencoop
Advisor
Advisor

Hi @mnpatric,

 

@Kent1Cooper has identified the problems in finding the "center", and @john.uhden has  given you some code to work with.  After reading through this thread it seems like you really want the text to land inside the polyline near what would be the centroid of a REGION described by the polyline rather than being put at the very difficult to define "center" of it.

 

Try this code and see if it gets you close to what you need.  It draws unit circles now so if they are where you want your text just put your text placement code where the circle command is:

 

;;;
;;;	Author: Henry C. Francis
;;;		425 N. Ashe St.
;;;		Southern Pines, NC 28387
;;;
;;;	http://www.paracadd.com
;;;	All rights reserved.
;;;
;;;	Copyright:	4/6/2017
;;;	   Edited:	4/6/2017
;;;
(defun c:polycntr (/ PCTR:cmde polyss polyss-cnt anobj plename plwasopen newent rgnobj rgnctr)
; c:polycntr Works for both Polylines and 2DPolylines
  (setq PCTR:cmde (getvar "CMDECHO"))
  (SETVAR "CMDECHO" 0)

; For automatic polyline selection you may use anything similar to the following that matches your needs
  (setq polyss (ssget '((0 . "*POLYLINE")(8 . "Your Layer Name")))); Selects all polylines on the layer named "Your Layer Name"
  (IF polyss
    (progn
      (setq polyss-cnt 0)
      (while (< polyss-cnt (sslength polyss))
        (setq anobj (vlax-ename->vla-object (setq plename (ssname polyss polyss-cnt))))

; For single polyline selection remove the ; from the next 2 lines and put a ; in front of the previous 6 lines
;  (while 
;    (setq anobj (vlax-ename->vla-object (setq plename (car (entsel)))))

        (if (wcmatch (vla-get-objectname anobj) "AcDbPolyline,AcDb2dPolyline")
          (progn
            (if (not (= (vla-get-closed anobj) :vlax-true))
              (progn
                (setq plwasopen T)
                (vla-put-closed anobj -1)
              )
              (setq plwasopen NIL)
            )
            (command ".region" plename "")
            (setq newent (entlast))
            (if (and newent
                     (setq rgnobj (vlax-ename->vla-object newent))
                     (= (vla-get-objectname rgnobj) "AcDbRegion")
                )
              (progn
                (setq rgnctr (vlax-safearray->list (vlax-variant-value (vla-get-centroid rgnobj))))
                ; rgnctr is the centroid point of the current polyline
                (command ".undo" 1)
; Replace the following circle command your text placement code 
                (command ".circle" rgnctr 20.0)
                (if plwasopen
                  (progn
                    (setq plwasopen NIL)
                    (vla-put-closed anobj 0)
                  )
                )
              )
              (princ "\nCould not determine the centroid of the polyline! ")
            )
          )
          (princ "\nNo polyline was selected! ")
        )

; Remove the ; from this next line if the single selection lines above are used
;  )

; Comment out the next 4 lines if you need single selection
          (setq polyss-cnt (1+ polyss-cnt))
        )
      )
    )

  (SETVAR "CMDECHO" PCTR:cmde)
  (PRINC)
) ;_ end of defun
AutoCAD User since 1989. Civil Engineering Professional since 1983
Product Version: 13.6.1963.0 Civil 3D 2024.4.1 Update Built on: U.202.0.0 AutoCAD 2024.1.6
                        27.0.37.14 Autodesk AutoCAD Map 3D 2024.0.1
                        8.6.52.0 AutoCAD Architecture 2024
Message 12 of 15

stevor
Collaborator
Collaborator

1. Two examples of centroid:

David.Hoole -  forums.augi.com/archive/index.php/t-5641.html

Lee Mac  - lee-mac.com/polygoncentroid.html

 

2. For a central text location, you may need to find

the largest rectangle in the polygon, or longest.

S
Message 13 of 15

hencoop
Advisor
Advisor

I should have pointed out that the code as it is written will only find Polylines and 2DPolylines on a layer named "Your Layer Name".  The intention was for you to replace this name with your own or else remove (8 . "Your Layer Name") entirely from the SSGET function in order to select them on any layer.

AutoCAD User since 1989. Civil Engineering Professional since 1983
Product Version: 13.6.1963.0 Civil 3D 2024.4.1 Update Built on: U.202.0.0 AutoCAD 2024.1.6
                        27.0.37.14 Autodesk AutoCAD Map 3D 2024.0.1
                        8.6.52.0 AutoCAD Architecture 2024
0 Likes
Message 14 of 15

mnpatric
Enthusiast
Enthusiast

thanks

0 Likes
Message 15 of 15

mnpatric
Enthusiast
Enthusiast

thanks

0 Likes