Rectangle sizing, Text & Dimension

Rectangle sizing, Text & Dimension

Anonymous
Not applicable
2,295 Views
7 Replies
Message 1 of 8

Rectangle sizing, Text & Dimension

Anonymous
Not applicable

Dear Autodesk group members, specially all programmers i need your help on this topic (it will be great if any one can help me on same)

i am looking to create a LISP for my project need for AUTOCAD 2017.

 

I want to create a Rectangle in specific layer with customized command then i want to give L & W to that rectangle on run time, so that after completion/in mid of command i will get rectangle of required size, then once rectangle is created i want to get a popup message that autocad shall ask me to give Name of rectangle which i want to place by default in the center of rectangle created.

 

i want to do this for different rectangles to be created.

 

i created customized command to create specific rectangle layer current followed by i created rectangle using below code at the moment. I am not in touch with LISP writing for 10 yrs & forgot most of the things and my previous codes are not working in new version. Please can anyone help me on same. it will be a great help from you, thanking you in advance for your kind support on same. i need it urgently.

 

(defun _SetCLayer (layerName)
(if (tblsearch "layer" layerName)
(setvar 'clayer layerName)
(prompt
(strcat "\n** Layer \"" layerName "\" not found ** ")
)
)
(princ)
)
(defun c:ACDB () (_SetCLayer "AC_DB") (command "RECTANG" "")) - in this autocad is also giving some violations.
(defun c:ACON () (_SetCLayer "AIR_CON") (command "RECTANG"))
(defun c:FBAT () (_SetCLayer "BATTERY") (command "RECTANG"))
(defun c:FBEN () (_SetCLayer "BUILDING_ENVELOPE") (command "RECTANG"))
(defun c:FCAB () (_SetCLayer "CABINET") (command "RECTANG"))
(defun c:DCDB () (_SetCLayer "DC_DB") (command "RECTANG"))
(defun c:FDEF () (_SetCLayer "Defpoints") (command "RECTANG"))
(defun c:FPDI () (_SetCLayer "DIMENSIONS") (command "RECTANG"))
(defun c:FPDR () (_SetCLayer "DOORS") (command "RECTANG"))
(defun C:FFED () (_SetCLayer "FEEDER") (command "RECTANG"))
(defun c:FPLD () (_SetCLayer "FLOOR_LEGEND") (command "RECTANG"))
(defun c:IMGI () (_SetCLayer "Image") (command "RECTANG"))
(defun c:FOTR () (_SetCLayer "OTHER") (command "RECTANG"))
(defun c:FRAK () (_SetCLayer "RACK") (command "RECTANG"))
(defun c:FREF () (_SetCLayer "RECTIFIER") (command "RECTANG"))
(defun c:FTEX () (_SetCLayer "TEXT") (command "RECTANG"))

)

 

In past i used below command to give text, which is now not working

(defun C:ACDBT ()
(setq bldg_no (strcase (getstring "/n Type the ACDB NO: ")))
(setq bldgno (strcat "ACDB" bldg_no))
(polbldgno)
(command "clayer" "AC_DB" "" "text" fspt txtht angpts bldgno "")
)

 

So finally my requirement is for floor plans i have to create:

1. Rectangle in current specific layer where i should get pop-up to give L & W.

2. Text in the center of that rectangle "with pop up to enter only number after concatenated Specific text"

3. After creation of all rectangles i want to give dimension to all rectangles in on go by selecting them.

0 Likes
Accepted solutions (2)
2,296 Views
7 Replies
Replies (7)
Message 2 of 8

Darin.Green
Mentor
Mentor

@Anonymous

 

I found this lisp that does exactly what you're looking for... However, you'll still need to add your code for setting the layers, etc.

 

 

Reference: https://groups.google.com/forum/#!topic/comp.cad.autocad/MqIlot9iaac

 

(defun C:RECTLINE (/ pt1 pt2 pt3 pt4 oldbw oldbh)
 (initget "Width")
 (setq pt1 (getpoint "\nFirst corner or Press Enter For <Width/Height>: "))
 (if (not pt1) (setq pt1 "Width"))
 (cond ((/= pt1 "Width")
        (while pt1
          (setq pt3 (getcorner pt1 " Other corner: "))
          (setq pt2 (list (car pt3) (cadr pt1)))
          (setq pt4 (list (car pt1) (cadr pt3)))
          (setq os (getvar "osmode")) (setvar "osmode" 0)
          (command "LINE" pt1 pt2 pt3 pt4 "C")
          (setvar "osmode" os)
          (setq pt1 (getpoint "\nFirst corner: "))
        )
       )
       ((= pt1 "Width")
        (if bw (setq oldbw bw) (setq oldbw 0.5))
        (initget  2)
        (setq bw (getdist (strcat "\nRectangle width <" (rtos oldbw)
">:")))
        (if (not bw) (setq bw oldbw))
        (if bh (setq oldbh bh) (setq oldbh 0.5))
        (initget 2)
        (setq bh (getdist (strcat "\nRectangle height <" (rtos oldbh)
">:")))
        (if (not bh) (setq bh oldbh))
        (while
          (setq pt1 (getpoint "\nIndicate reference corner of box: "))
          (setq pt2 (list (+ (car pt1) bw) (cadr pt1)))
          (setq pt3 (list (+ (car pt1) bw) (+ (cadr pt1) bh)))
          (setq pt4 (list (car pt1) (+ (cadr pt1) bh)))
          (setq os (getvar "osmode")) (setvar "osmode" 0)
          (command "LINE" pt1 pt2 pt3 pt4 "C")
          (setvar "osmode" os)
        )
       )
 )
 (prin1)
)

 



If this information was helpful, please consider using the Accept Solution


0 Likes
Message 3 of 8

Anonymous
Not applicable

Dear Darin.Green,

 

Thanks for your support to solve my Point 1 requirement partially but this is little bit different then i am looking for, this code will allow me to create rectangle on run time by giving L & W for my point 1.

 

My exact need is as given below:

My requirement is for floor plans i have to create:

1. Rectangle in specific current layer where i should get pop-up to give L & W after making any specific rectangle layer as current layer.

2. Text in the center of that rectangle "with pop up to enter only number after concatenated Specific text" after making any specific Text layer as current layer.

3. After creation of all rectangles i want to give dimension to all rectangles in on go by selecting them after making any specific Dimension layer as current layer.

 

I was using below code for point 1 requirement without run-time L & W and getting violations message from autocad interface for rectangle command. while my requirement of point 2 & 3 is open.

    (defun _SetCLayer (layerName)
(if (tblsearch "layer" layerName)
(setvar 'clayer layerName)
(prompt
(strcat "\n** Layer \"" layerName "\" not found ** ")
)
)
(princ)
)
(defun c:ACDB () (_SetCLayer "AC_DB") (command "RECTANG" "")).

 

 

0 Likes
Message 4 of 8

Kent1Cooper
Consultant
Consultant
Accepted solution

@Anonymous wrote:

.... 

I want to create a Rectangle in specific layer with customized command then i want to give L & W to that rectangle ... then once rectangle is created i want to get a popup message that autocad shall ask me to give Name of rectangle which i want to place by default in the center of rectangle created.

....
(defun c:ACDB () (_SetCLayer "AC_DB") (command "RECTANG" "")) - in this autocad is also giving some violations.
....

So finally my requirement is for floor plans i have to create:

1. Rectangle in current specific layer where i should get pop-up to give L & W.

2. Text in the center of that rectangle "with pop up to enter only number after concatenated Specific text"

3. After creation of all rectangles i want to give dimension to all rectangles in on go by selecting them.


I don't understand the idea of drawing a rectangle and then being asked for its length and width, which means you would need to modify the rectange just drawn.  Ask for the dimensions first, then draw it, or better yet, use the Dimensions option in the RECTANG command -- it will ask you for the length and width itself.

 

That line that is causing "violations" has an extra Enter [""] that is not in the other commands, which is probably causing the problem.

 

For the text content, there's an undocumented function called (lisped) that will bring up a text-editing box with whatever you specify already in it, and you can just add what you want -- you don't need to get pieces and put them together.

 

There are routines around to automatically dimension Polylines -- some Searching will find several.

 

For the Layer, there's no need to check whether it exists.  Just use the Make option, and if it already exists, it will be set current, and if it doesn't exist yet, it will make it and set it current.  You can build in color and linetype [etc.] options too, if you want.

 

You did not include the definition of the (polbldgno) function, nor how the fspt, txtht or angpts variables are determined, so we can't diagnose problems that might be coming from those.

 

I would try something along these lines [untested]:

 

(vl-load-com)

(defun recttxt (layname prefix)

  (command

    "_.layer" "_make" layname ""

    "_.rectang" pause "_dimensions" pause pause pause

    "_.text" "_mc" "_none"

      (mapcar '/ ; calculate midpoint of rectangle [in place of fspt, I assume]

        (mapcar '+

          (vlax-curve-getStartPoint (entlast))

          (vlax-curve-getPointAtParam (entlast) 2)

        ); mapcar +

        '(2 2 2)

      ); mapcar /

      txtht angpts [or should the rotation always be 0?]

      (lisped prefix); text content with prefix built in

  ); command

  (princ)

); defun

 

And then for each Layer, call that function and feed in the Layer name and associated Text prefix, for example:

 

(defun C:ACDB () (recttxt "AC_DB" "ACDB"))

 

I would also strongly recommend that you include a setting of the Style in the Text command, rather than just using whatever Style happens to be current.  If some other Style is current and has a non-zero fixed height, it will throw this off, because there will be no prompt for the height, so setting the Style will also prevent that if the Style specified for these has zero defined height.  Or you can define a Style with a fixed height, and leave out the height response in the command.

Kent Cooper, AIA
Message 5 of 8

Anonymous
Not applicable

You'll probably have MUCH better luck posting your LISP specific questions here:

https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/bd-p/130

 

or 

 

www.swamp.org

 

 

Message 6 of 8

Anonymous
Not applicable

Dear Kent,

 

Thanks a ton for solution provided and elaborated by you. It helped me to create Polygon in current layer and followed by that it is asking for additional text after prefix but it is not allowing to place / it is throwing it out.

I found some routines around to automatically dimension Polylines by Searching but they are working for individual entity instead of all selected entity.

Here is my definition of the (polbldgno) function with fspt, txtht or angpts variables.

 

[code]

 

(defun polbldgno ()
;(security)
(setvar "cmdecho" 0)
(setq fspt (getpoint "\n Pick start point of text: "))
(prompt "\n Pick fit (last) point for fitting text inside polygon: ")
(command "line" fspt pause "")
(setq entt (entlast))
(setq secpt (cdr (assoc 11 (entget entt))))
(command "erase" entt "")
;(setq secpt (getpoint "\n Pick fit (last) point for fitting text inside polygon: "))
(setq dst (distance fspt secpt))
(setq angpts (* (angle fspt secpt) 57.xxx-xxxxxxxx))
(setq chr_nos (strlen bldgno))
(setq cc 1)
(setq no_ii 0)
(setq no_11 0)
(setq no_// 0)
(repeat chr_nos
(setq char (substr bldgno CC 1))
(cond ((= char "I")(setq no_ii (+ no_ii 1))))
(cond ((= char "1")(setq no_11 (+ no_11 1))))
(cond ((= char "/")(setq no_// (+ no_// 1))))
(setq cc (+ cc 1))
)
(setq no_oth (- chr_nos (+ no_ii no_11 no_//)))
(setq chr_len (+ (* 1 no_oth) (* no_ii 0.3)(* no_11 0.55)(* no_// 0.7)))
(setq factr (/ dst chr_len ))
(cond ((and (> factr 2.5)(< factr 10.0))(setq txtht 30.0)))
(cond ((and (> factr 2.0)(< factr 2.5))(setq txtht 2.0)))
(cond ((and (> factr 1.5)(< factr 2.0))(setq txtht 1.5)))
(cond ((and (> factr 1.25)(< factr 1.5))(setq txtht 1.25)))
(cond ((and (> factr 1.0)(< factr 1.25))(setq txtht 1.0)))
(cond ((and (> factr 0.75)(< factr 1.0))(setq txtht 0.75)))
(cond ((and (> factr 0.6)(< factr 0.75))(setq txtht 0.6)))
(cond ((and (> factr 0.5)(< factr 0.6))(setq txtht 0.5)))
(cond ((and (> factr 0.4)(< factr 0.5))(setq txtht 0.4)))
(cond ((and (> factr 0.3)(< factr 0.4))(setq txtht 0.3)))
(cond ((and (> factr 0.25)(< factr 0.3))(setq txtht 0.25)))
(cond ((and (> factr 0.2)(< factr 0.25))(setq txtht 0.2)))
(cond ((< factr 0.2)(setq txtht 0.15)))
);defun polbldgno

 

[/code]

0 Likes
Message 7 of 8

Kent1Cooper
Consultant
Consultant
Accepted solution

The (lisped) function doesn't throw out / characters for me.  Can you be more specific about what you're doing?

 

For dimensioning Polylines, any routine that works on one can be adjusted rather easily to work on a selection of more than one.  Is there one you have found that does it [on one Polyline] in a way that you like better than others?

 

That long function looks like it's deciding what height to give the Text depending on the characters in it, and rotation angle, so that it will fit [roughly] between the picked points.  If that's what it's doing, you must not be aware of ALIGNED Text justification.  Start a Text command, type A for Aligned justification, give it two points and the contents, and it will fit it in, not just roughly but precisely between those points [endpoints of the baseline], adjusting the height as necessary, and also using the angle between those two points, so you don't need to calculate that, either.  There's also a FIT justification, which also uses two endpoints, but a specified height, and what it adjusts is the width of the characters to fit the length [and angle] between those endpoints at that height.  Read about them in Help.  Either of those would greatly simplify that routine.  [There are other things that could be improved about the code, but many of them won't be relevant if you change to Aligned or Fit justification.]

Kent Cooper, AIA
Message 8 of 8

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

You'll probably have MUCH better luck posting your LISP specific questions here:

https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/bd-p/130

.... 


That suggestion has been accepted -- see the continuation of this topic over there.

Kent Cooper, AIA