Jump to content

entmake block with attributes, scale and rotation issue


CHLUCFENG

Recommended Posts

I have done quite a search and have not found any good explanation to use entmake to insert a defined block, and scale or rotate that block upon insertion.

 

The idea is to tag a line (pipe), and add the diameter, length, and cut-length of that pipe using attributes. I have the code to get the line information ready, and was working on the entmake for the attribute block to label the "pipes".

 

Here is the code for the attribute block:

(defun c:apd (/ LAY1 LAY2 LAY3 LAY4
        CLR1 CLR2 CLR3 CLR4
        LTP1 LTP2 LTP3 LTP4
        FONT value1 value2 value3
        rotation p)


;;; Change layer names and colors to suit user.
 (setq	LAY1   "S-Pipe-Detail"
LAY2   "S-Pipe-Dia"
LAY3   "S-Pipe-Length"
LAY4   "S-Pipe-Cut"
CLR1   1
CLR2   2
CLR3   3
CLR4   4
LTP1   "Continuous"
LTP2   "Continuous"
LTP3   "Continuous"
LTP4   "Continuous"
FONT   "Standard"
 )

;;;======================== Block Definition ======================

(defun DEF_PipeDetail ()	;generated using EntMaker CAB 04- MakeEntmake.lsp
 (entmake '((0 . "BLOCK")
     (100 . "AcDbEntity")
     (67 . 0)
     (8 . "0")
     (100 . "AcDbBlockReference")
     (66 . 1)
     (2 . "PipeDetail")
     (10 0.0 0.0 0.0)
     (70 . 2)
    )
 )
 (entmake '((0 . "ATTDEF")
     (100 . "AcDbEntity")
     (67 . 0)
     (8 . "S-Pipe-Dia")
     (100 . "AcDbText")
     (10 0.0 0.0 0.0)
     (40 . 0.095833333333331)
     (1 . "-DIA-")
     (50 . 0.0)
     (41 . 0.
     (51 . 0.0)
     (7 . "Standard")
     (71 . 0)
     (72 . 1)
     (100 . "AcDbAttributeDefinition")
     (280 . 0)
     (3 . "PIPE DIAMETER:")
     (2 . "DIA")
     (70 . 0)
     (74 . 1)
     (280 . 0)
    )
 )
 (entmake '((0 . "ATTDEF")
     (100 . "AcDbEntity")
     (67 . 0)
     (8 . "S-Pipe-Length")
     (100 . "AcDbText")
     (10 0.0 0.0 0.0)
     (40 . 0.095833333333331)
     (1 . "-LENGTH-")
     (50 . 0.0)
     (41 . 0.
     (51 . 0.0)
     (7 . "Standard")
     (71 . 0)
     (72 . 1)
     (100 . "AcDbAttributeDefinition")
     (280 . 0)
     (3 . "PIPE LENGTH:")
     (2 . "PIPELENGTH")
     (70 . 0)
     (74 . 3)
     (280 . 0)
    )
 )
 (entmake '((0 . "ATTDEF")
     (100 . "AcDbEntity")
     (67 . 0)
     (8 . "S-Pipe-Cut")
     (100 . "AcDbText")
     (10 0.0 0.0 0.0)
     (40 . 0.095833333333331)
     (1 . "-LENGTH-")
     (50 . 0.0)
     (41 . 0.
     (51 . 0.0)
     (7 . "Standard")
     (71 . 0)
     (72 . 1)
     (100 . "AcDbAttributeDefinition")
     (280 . 0)
     (3 . "CUT LENGTH:")
     (2 . "CUTLENGTH")
     (70 . 0)
     (74 . 3)
     (280 . 0)
    )
 )
 (entmake '((0 . "ENDBLK") (100 . "AcDbBlockEnd") (8 . "0")))
 (princ)
)					; end DEF_PipeDetail


;;;======================== Insert Block ======================

(defun insert_PipeDetail (p lay rot d_lay pl_lay cl_lay font value1 value2 value3)
 (entmake (list (cons 0 "INSERT")
	 (cons 2 "PipeDetail")
	 (cons 10 p)
	 (cons 8 lay)
	 (cons 66 1)
	 (cons 62 256)
	 (cons 39 0)
	 (cons 6 "BYLAYER")
	 (cons 50 rot);block rotation (radians)
   )
 )

 (entmake (list (cons 0 "ATTRIB")
	 (cons 8 d_lay)
	 (cons 10 (mapcar '* (mapcar '+ p '(0.0 0.046875 0.0)) (list (getvar "textsize")(getvar "textsize")(getvar "textsize"))))
	 (cons 11 (mapcar '+ p '(0.0 0.140625 0.0)))
	 (cons 40 (getvar "textsize"));text height
	 (cons 1 Value1)
	 (cons 2 "DIA")
	 (cons 70 0);attr flag
	 (cons 50 0);text rot
	 (cons 41 1);relative x-factor, width
;;;		 (cons 51 0);oblique angle (default 0)
	 (cons 7 font)
;;;		 (cons 71 0);text flag (def 0, bkwrd 2, upside dn 4)
	 (cons 74 1);1 BCenter
	 (cons 72 1);1 Center
	 (cons 210 (list 0 0 1));extrusion (def 0,0,1)
;;;		 (cons 73 0)
	 (cons 62 256);color (bylayer 256)
;;;		 (cons 39 0);thickness (def 0)
	 (cons 6 "BYLAYER")
   )
 )
(entmake (list (cons 0 "ATTRIB")
	 (cons 8 pl_lay)
	 (cons 10 (mapcar '* (mapcar '+ p '(-0.046875 -0.140625 0.0)) (list (getvar "textsize")(getvar "textsize")(getvar "textsize"))))
       	 (cons 11 (mapcar '+ p '(-0.046875 -0.140625 0.0)))
	 (cons 40 (getvar "textsize"));text height
	 (cons 1 Value2)
	 (cons 2 "PIPELENGTH")
	 (cons 70 0);attr flag
	 (cons 50 0);text rot
	 (cons 41 1);relative x-factor, width
;;;		 (cons 51 0);oblique angle (default 0)
	 (cons 7 font)
;;;		 (cons 71 0);text flag (def 0, bkwrd 2, upside dn 4)
	 (cons 74 3);3 TCenter
	 (cons 72 1);1 Center
	 (cons 210 (list 0 0 1));extrusion (def 0,0,1)
;;;		 (cons 73 0)
	 (cons 62 256);color (bylayer 256)
;;;		 (cons 39 0);thickness (def 0)
	 (cons 6 "BYLAYER");linetype name
   )
 )
 (entmake (list (cons 0 "ATTRIB")
	 (cons 8 cl_lay)
	 (cons 10 (mapcar '* (mapcar '+ p '(0.046875 -0.28125 0.0)) (list (getvar "textsize")(getvar "textsize")(getvar "textsize"))))
	 (cons 11 (mapcar '+ p '(0.046875 -0.28125 0.0)))
	 (cons 40 (getvar "textsize"));text height
	 (cons 1 Value3)
	 (cons 2 "CUTLENGTH")
	 (cons 70 0);attr flag
	 (cons 50 0);text rot
	 (cons 41 1);relative x-factor, width
;;;		 (cons 51 0);oblique angle (default 0)
	 (cons 7 font)
;;;		 (cons 71 0);text flag (def 0, bkwrd 2, upside dn 4)
	 (cons 74 3);3 TCenter
	 (cons 72 1);1 Center
	 (cons 210 (list 0 0 1));extrusion (def 0,0,1)
;;;		 (cons 73 0)
	 (cons 62 256);color (bylayer 256)
;;;		 (cons 39 0);thickness (def 0)
	 (cons 6 "BYLAYER");linetype name
   )
 )

 
 (entmake (list
     (cons 0 "SEQEND")
     (cons 8 lay)
   )
 )
)


;;;======================== Make Layers ======================

(defun make_layer (MyLayer MyColor MyLtype)
 (entmake (list (cons 0 "LAYER")
       (cons 100 "AcDbSymbolTableRecord")
       (cons 100 "AcDbLayerTableRecord")
       (cons 2 MyLayer)
       (cons 6 MyLtype)
       (cons 62 MyColor)
	(cons 70 0)
 )
 )
)

;;;======================== Main Function =======================

 (if (not (tblsearch "layer" LAY1))
   (make_layer LAY1 CLR1 LTP1)
 )
 (if (not (tblsearch "layer" LAY2))
   (make_layer LAY2 CLR2 LTP2)
 )
 (if (not (tblsearch "layer" LAY3))
   (make_layer LAY3 CLR3 LTP3)
 )
 (if (not (tblsearch "layer" LAY4))
   (make_layer LAY4 CLR4 LTP4)
 )
 
 (if (not (tblsearch "block" "PipeDetail"))
   (DEF_PipeDetail)
 )

 ;;; temporary setq
(setq value1 "MyDiameter"
     value2 "MyLength"
     value3 "MyCut"
     rotation 1.5708
)
 ;;; end temporary setq

 (setvar "osmode" 512)
 (while
   (setq p (getpoint "\nPick insertion point >> "))
    (insert_PipeDetail p LAY1 rotation LAY2 LAY3 LAY4 FONT value1 value2 value3)
 )
;;;end while
 (princ)
)

 

This code works, but I cannot get the lower two attributes to offset from the line (by half the text height), nor can I get the entire block to rotate (I used rotation 1.5708, or 90 degrees).

 

If anyone can enlighten me, or kick me in the right direction it would be much appreciated.

 

Thanks, CHL

Link to comment
Share on other sites

As you're probably finding out, it can be a very complex operation. Sometimes it's just easier to use a (command ) call and sequential inputs to INSERT / SCALE / ROTATE / ANNOTATE.

 

By using ( entmake ), You have almost complete control over the INSERT. However, all the parameters plus a few other sysvars must be taking in to account and calculated.

 

Most of the block table definitions for the ATTDEF can be manipulated at will.

Link to comment
Share on other sites

I'd suggest doing some cleanup (avoid setq's and repetition: use lists with subfuncitons instead) :

(defun C:test ( / make_layer DEF_PipeDetail insert_PipeDetail p a )
 ; local defuns: 
 (defun make_layer (MyLayer MyColor MyLtype)
   (or (tblsearch "LAYER" MyLayer)
     (entmake 
       (list 
         (cons 0 "LAYER") (cons 100 "AcDbSymbolTableRecord") (cons 100 "AcDbLayerTableRecord")
         (cons 2 MyLayer) (cons 6 MyLtype) (cons 62 MyColor) (cons 70 0)
       )
     )
   )
 ); defun make_layer
 
 
 (defun DEF_PipeDetail ( / AttDef )
   (defun AttDef ( dxf8 dxf1 dxf3 dxf2 )
     (list
       '(0 . "ATTDEF") '(100 . "AcDbEntity") (cons 8 dxf8)
       '(100 . "AcDbText") '(10 0.0 0.0 0.0) (cons 40 (getvar 'textsize))
       (cons 1 dxf1) '(50 . 0.0) '(41 . 0. '(51 . 0.0) '(7 . "Standard")
       '(71 . 0) '(72 . 1) '(100 . "AcDbAttributeDefinition") '(280 . 0) 
       (cons 3 dxf3) (cons 2 dxf2) '(70 . 0) '(74 . 1) '(280 . 0)
     )
   ); defun AttDef
   (or (tblsearch "BLOCK" "PipeDetail")
     (mapcar 'entmake
       (append
         '(((0 . "BLOCK") (100 . "AcDbEntity") (67 . 0) (8 . "0") (100 . "AcDbBlockReference") (66 . 1) (2 . "PipeDetail") (10 0.0 0.0 0.0) (70 . 2))) 
         (mapcar '(lambda (x) (apply 'AttDef x))
           '(("S-Pipe-Dia" "-DIA-" "PIPE DIAMETER:" "DIA")
             ("S-Pipe-Length" "-LENGTH-" "PIPE LENGTH:" "PIPELENGTH")
             ("S-Pipe-Cut" "-LENGTH-" "CUT LENGTH:" "CUTLENGTH")
           )
         )
         '(((0 . "ENDBLK") (100 . "AcDbBlockEnd") (8 . "0")))
       )
     )
   )
 ); defun DEF_PipeDetail
 
 
 (defun insert_PipeDetail (p lay rot atts / Attrib)
   (defun Attrib ( p rot dxf8 dxf1 dxf2 dxf7 yf )
     (list 
       (cons 0 "ATTRIB")
       (cons 8 dxf8)
       (cons 10 (polar p (+ (/ PI 2.) rot) (* yf (getvar 'textsize))))
       (cons 11 (polar p (+ (/ PI 2.) rot) (* yf (getvar 'textsize))))
       (cons 40 (getvar 'textsize)); Text height
       (cons 1 dxf1)
       (cons 2 dxf2)
       (cons 70 0)                 ; attr flag
       (cons 50 rot)               ; text rot
       (cons 41 1)                 ; relative x-factor, width
       (cons 51 0)                 ; oblique angle (default 0)
       (cons 7 dxf7)               ; Text style name
       (cons 71 0)                 ; text flag (def 0, bkwrd 2, upside dn 4)
       (cons 74 1)                 ; 1 BCenter
       (cons 72 1)                 ; 1 Center
       (cons 210 (list 0 0 1))     ; extrusion (def 0,0,1)
       (cons 73 0)                 ; Field length (optional; default = 0) (not currently used)
       (cons 62 256)               ; color (bylayer 256)
       (cons 39 0)                 ; thickness (def 0)
       (cons 6 "BYLAYER")
     )
   ); defun Attrib
   (if (tblsearch "BLOCK" "PipeDetail")
     (mapcar 'entmake
       (append
         (list
           (list  
             (cons 0 "INSERT") (cons 100 "AcDbEntity") (cons 8 lay) (cons 100 "AcDbBlockReference") (cons 66 1) (cons 2 "PipeDetail")
             (cons 10 p) (cons 41 1.0) (cons 42 1.0) (cons 43 1.0) (cons 50 rot) (cons 62 256) (cons 6 "BYLAYER")
           )
         )
         (mapcar '(lambda (x) (apply 'Attrib (append (list p rot) x))) atts)
         (list (list (cons 0 "SEQEND") (cons 8 lay)))
       )
     )
   ); if 
 ); defun insert_PipeDetail
 
 ; Main function:
 
 (mapcar ; create the layers
   '(lambda (x) (apply 'make_layer x))
   '( ("S-Pipe-Detail" 1 "Continuous") ("S-Pipe-Dia" 2 "Continuous") ("S-Pipe-Length" 3 "Continuous") ("S-Pipe-Cut" 4 "Continuous") )
 ); mapcar
 (DEF_PipeDetail) ; create the block definition
 (while ; prompt to create inserts
   (and
     (setq p (getpoint "\nPick insertion point >> ")) 
     (setq a (cond ((getreal "\nSpecify block rotation (in degrees) <0>: ")) (0.)))
   ); and
   (insert_PipeDetail p "S-Pipe-Detail" (* PI (/ a 180))
     '( ; atts
       ("S-Pipe-Dia" "MyDiameter" "DIA" "Standard" 1.5)
       ("S-Pipe-Length" "MyLength" "PIPELENGTH" "Standard" 0.0)
       ("S-Pipe-Cut" "MyCut" "CUTLENGTH" "Standard"  -1.5)
     )
   )
 ); while
 
 (princ)
); defun

Link to comment
Share on other sites

Thank you David for your response. You have come to my aid in the past.

 

Very much thank you Grrr, that is what I was looking for. Also thank you for the cleanup. I haven't gotten to that point yet (as seen from so many remarks all over the code). This is actually part of a larger program that will extract data from the selected line, then insert the attribute block. Which I will also clean up once I get working correctly. Nevertheless, you have illustrated some excellent cleanup methods that I will try to incorporate into future code.

 

Once again, Thank You.

Link to comment
Share on other sites

I would go like David so easy you already have all the answers. Using entmake is faster but if your doing one block at time and picking you will not see any down time. You only need to make the block once you can cut and paste out of another dwg or save it as part of your DWT.

 

(command "INSERT"  blkname pt x "" ang att1 att2 att3)

Link to comment
Share on other sites

Understood BIGAL, that is how we have been doing things for years, where blockname is a long string such as "G:\ACAD-BLOCKS\PLUMBING\PIPEDETAIL.dwg".

I am trying to cleanup menu's and routines to avoid the need for the path for the countless number of blocks we have here at the office for four disciplines. With so many blocks, that would also make the template file bulky.

 

Another reason for eliminating the large block library on the network, and using entmake to create the blocks, layers, etc. on the fly is that with the new Autodesk subscriptions, the users at work have the option to use their ACAD seat on their home computer. Rather than having every individual who works from home occasionally copy the entire block directory to their home hard drive, then map a folder to appear as "G-drive", it is much more beneficial to use entmake/x on our menus/routines.

 

And, sure I could create the definition, then go back to the old "command" call, but that does not help me to learn the entmake way of inserting the file after the definition. Every little program thus becomes a learning tool, and I have gleaned much from the code presented by Grrr. Especially some clever ways on how I should work to clean up much of the code we already have in place.

 

Thanks all,

CHL

Link to comment
Share on other sites

You can put all your blocks into 1 dwg and use Lee-mac's Steal lisp its 2 lines of code required to get a block out of another dwg. You load steal then just run a defun with the blockname. I use menus with images so the pathing is in the menu. you would need 2 menu's one with say C:\dwgs and the other the network G:.

 

If you dont want g:\\mynetwork\projects\blocks\pipes you can map a drive or a subdirectory back to a single letter plus add last directory B:\pipes for blocks its part of the windows operating system.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...