The ENTMAKE and ENTMAKEX functions are often forgotten elements of the AutoLISP programming environment because the use of the COMMAND function to call a command line LINE and CIRCLE are so tempting and easy. Why reinvent the wheel if you do not need to, or in this case the functionality.
Both ENTMAKE and ENTMAKEX allow you to create new graphical and non-graphical objects without using the COMMAND function. This allows you to create a line and assign it a specific layer without first changing the layer with the Layer command and then calling the Line command to create the line and then restore the previous layer. Not bad, but if you think about it further you need to turn off command echoing (CMDECHO) to keep the command line clean, drawing off screen or outside the drawing limits at times, and worry about the current running object snaps.
So after writing a few articles on the SETPROPERTYVALUE and GETPROPERTYVALUE functions the last few days I decided to go one step further and show how to create some new objects without the COMMAND function and then update their properties. The following sample shows how to create a line, circle, and layer prior to updating their properties.
NOTE: The helper function (AddObj) does all the object creation work.
;; Begin Code
;; Create a new layer and change its plowable state, then
;; create a new line and circle without using the command function
;; 8/20/11 - Lee Ambrosius
(defun c:newObjects ( / layEnt newObj)
;; Create a new Layer named Const if it does not exist
(if (= (setq layEnt (tblobjname "layer" "Const")) nil)
(progn
(setq layEnt (addobj "Layer"))
;; Update the new layers name
(setpropertyvalue layEnt "Name" "Const")
;; Set the color of the new layer
;; Color can be ACI (6), true color (125,125,125),
;; or color book (PANTONE+ CMYK Coated,PANTONE P 1-3 C)
(setpropertyvalue layEnt "Color" "231,18,18")
;; Set the layer so it cannot be plotted
(setpropertyvalue layEnt "IsPlottable" 0)
)
)
;; Create a new line
(setq newObj (addObj "Line"))
;; Set the start and end point
(setpropertyvalue newObj "StartPoint" '(0.0 0.0 0.0))
(setpropertyvalue newObj "EndPoint" '(5.0 5.0 0.0))
;; Change the layer of the new line
(setpropertyvalue newObj "LayerID" layEnt)
;; Create a new circle
(setq newObj (addObj "Circle"))
;; Set the start and end point
(setpropertyvalue newObj "Center" '(5.0 5.0 0.0))
;; Change the layer of the new line
(setpropertyvalue newObj "LayerID" layEnt)
(princ)
)
;; Helper function to create the initial object without using the commands
(defun addObj (objType / newObj)
(setq newObj nil)
(cond
((= (strcase objType) "LINE")
(setq newObj (entmakex '((0 . "LINE")
(10 0.0 0.0 0.0) ; Start point
(11 1.0 1.0 1.0) ; End point
))
)
)
((= (strcase objType) "CIRCLE")
(setq newObj (entmakex '((0 . "CIRCLE")
(10 0.0 0.0 0.0) ; Center point
(40 . 1.0) ; Radius
))
)
)
((= (strcase objType) "LAYER")
(setq newObj (entmakex (list (cons 0 "LAYER")
(cons 100 "AcDbSymbolTableRecord")
(cons 100 "AcDbLayerTableRecord")
(cons 2 (strcat "TEMP-" (rtos (getvar "CDATE") 2 8))) ; Name
(cons 70 0) ; State
(cons 62 7) ; Color
(cons 6 "Continuous") ; Linetype
))
)
)
)
;; Return the new object
newObj
)
(prompt "\nType NEWOBJECTS to create a new line, circle, and layer without the COMMAND function.")
;; End Code
Sincerely,
Lee
Lee,
How about creating a more complex object using ENTMAKE like a multileader? What would the code look like to do that?
Posted by: John Loudermilk | Monday, August 22, 2011 at 08:14 AM
Let me see what I can cook up... I know I have been thinking about Table Styles as well for a future article.
Posted by: Lee Ambrosius | Monday, August 22, 2011 at 10:10 AM
I did a bit of digging and here is what I came up with, there might be some codes that cane be trimmed down to create a basic Mleader. You need to define the number of points you want in he Mleader when creating it as there does not seem to be a way to add additional points from what I noticed at a quick glance.
;; Mleader framework - Straight - 3 point
(setq newObj (entmakex '((0 . "MULTILEADER")
(100 . "AcDbEntity")
(100 . "AcDbMLeader")
;; No content
(300 . "CONTEXT_DATA{")
(10 22.4318 7.96727 0.0) ;; Start landing
(110 20.7384 6.13904 0.0) ;; Endpoint
(297 . 0)
;; Leader and landing
(302 . "LEADER{")
(290 . 1)
(291 . 1)
(10 22.4318 7.96727 0.0) ;; Start landing
(11 1.0 0.0 0.0)
(90 . 0)
(40 . 0.36)
(304 . "LEADER_LINE{")
(10 20.7384 6.13904 0.0) ;; Endpoint
(10 21.4304 7.79070 0.0) ;; Next point
(91 . 0)
(170 . 1)
(92 . -1056964608)
(171 . -2)
(40 . 0.0)
(93 . 0)
(305 . "}")
(271 . 0)
(303 . "}")
(272 . 9)
(273 . 9)
(301 . "}")
))
)
;; Mleader framework - Spline - 1 point
(setq newObj (entmakex '((0 . "MULTILEADER")
(100 . "AcDbEntity")
(100 . "AcDbMLeader")
(300 . "CONTEXT_DATA{")
(10 22.8629 7.06467 0.0)
(110 21.9268 5.87439 0.0)
(297 . 0)
(302 . "LEADER{")
(290 . 1)
(291 . 1)
(10 22.5029 7.06467 0.0)
(11 1.0 0.0 0.0)
(90 . 0)
(40 . 0.36)
(304 . "LEADER_LINE{")
(10 21.9268 5.87439 0.0)
(91 . 0)
(170 . 1)
(92 . -1056964608)
(171 . -2)
(40 . 0.0)
(93 . 0)
(305 . "}")
(271 . 0)
(303 . "}")
(272 . 9)
(273 . 9)
(301 . "}")
;; 90 and 170 control Spline behavior
(90 . 1025)
(170 . 2)
))
)
Posted by: Lee Ambrosius | Monday, August 22, 2011 at 12:03 PM