Inserting Blocks Using a Transformation Matrix (AutoLISP Solutions AutoCAD Tutorial)31 Oct, 2007 By: Tony Hotchkiss
This solution lets you add blocks to an AutoCAD drawing and place them in the correct position and orientation.
Rich Smith e-mailed me a request asking how to add blocks to an AutoCAD drawing using a transformation matrix to place the blocks in the correct position and orientation. In his scenario, a series of block names and values of a 4x4 transformation matrix are to be input from a comma-delimited (CSV) file.
The AutoLISP Solution is INSBLOCK4.LSP. The routine requests the location of the CSV file and reads the name of the drawing (block) to be inserted and 16 values representing the 4x4 transformation matrix for any number of blocks. The blocks are then inserted and transformed to their final x, y, and z locations and orientations in the current drawing.
Get the Code
Download the INSBLOCK4.LSP file from Cadalyst's CAD Tips site. Save the file in AutoCAD's Support directory. Use the Appload facility by selecting Tools / Load Application, and then use the browser to select the file.
How to Use the INSBLOCK4.LSP Code
To start the program, enter IB4 and you will see the Import (CSV) File dialog box as shown below.
The Import (CSV) File dialog box.
Browse to find the CSV file, and you will see the finished assembly of blocks located and oriented properly in the current drawing as shown in the two views below.
Top view of the assembled blocks.
Front view of the assembled blocks.
After my usual error and system variable management functions, the program contains two functions, INSBLK4 and PARSE.
I have used the Parse function in previous "AutoLISP Solutions" columns, so I decided to save time and programming by reusing the code. Parse takes a delimited string of characters, a delimiter code, and a field counter as its input arguments and returns the value of the field as a string. Thus, in this case, there are a total of 17 fields delimited by commas, and any one of the fields is returned depending on the number 1 through 17 that is given as the field counter input. The delimiter code is somewhat redundant in this case, because the file is designated as comma delimited. When I used this function previously, it referred to any type of delimiter, such as a space, semicolon, or comma. I decided to use the function as-is rather than change it in this particular case for two reasons: I was sure that it worked properly, and I like the old maxim -- if it ain't broke, don't fix it.
INSBLK4 is the main function that begins with some standard code taken straight from the AutoLISP Developer Guide to establish values for variables such as THISDRAWING, MODELSPACE, and PAPERSPACE. The standard GetFiled function is used to get the delimited file that contains the input data for the program. A While loop reads each line of the comma-delimited file and extracts each of the 17 fields via successive calls to Parse. The last 16 of these fields represent the transformation matrix that is set out as a 4 x 4 matrix as follows:
R00 R01 R02 T0
R10 R11 R12 T1
R20 R21 R22 T2
0 0 0 1
where R = rotation and T = translation. For each line of the comma-delimited file, the values of the rotations and translations are determined. I used the terminology R30, R31, R32, and T3 to represent the last row of the matrix and then the code to create the transformation matrix in AutoLISP is as follows:
'(0 . 3)
'(0 . 3)
) ;_ end of vlax-make-safearray
) ;_ end of setq\
(setq lst0 (list R00 R01 R02 T0 R10 R11 R12
T1 R20 R21 R22 T2 R30
R31 R32 T3) ;_ end of list
) ;_ end of setq
(setq i 0
) ;_ end of setq
(repeat (length lst0)
(vlax-safearray-put-element TM i j (nth k lst0))
(setq k (1+ k))
(setq j (1+ j))
(if (= j 4)
(setq j 0)
(setq i (1+ i))
) ;_ end of progn
) ;_ end of if
) ;_ end of repeat
(setq TransformationMatrix (vlax-make-variant TM))
In the code, the rotations are separated from the translation to avoid confusion because the AutoLISP matrix includes scaling factors if all four columns are used. The remaining code to insert the block and to complete the transformation uses the VLA-TransformBy method as follows:
(setq blkobj (vla-InsertBlock
(vlax-3D-point 0 0 0)
) ;_ end of vla-InsertBlock
) ;_ end of setq
(vla-TransformBy blkobj TransformationMatrix)
(vla-Move blkobj p0 transpt)
(vla-ScaleEntity blkobj p0 ScaleFactor)
) ;_ end of while
(vl-cmdf "ZOOM" "Extents")
(setq f (close f))
) ;_ end of insblk4
Here the While loop is closed, the CSV file is closed, and the INSBLK4 function is completed.
As always, I look forward to receiving your comments and requests for "AutoLISP Solutions." Contact me using the links below.