Auto-Breaking Blocks
I've had a lot of request to write a tutorial on creating
Auto-Breaking blocks.
These are very handy little objects and can save a draughtsman a lot of
time and effort. The only drawback to them is that they initially take a
bit of time to prepare. Let's have a look at what we need to do to go
about creating Auto-Breaking
blocks.
Firstly, we need to find some way of "storing" the break
point data within the block.
For this tutorial we are going to use attributes. Fire up AutoCAD and draw
a valve similar to the one shown here.
Now type in "DDATTDEF" at the command prompt. The
Attribute definition dialogue box will appear.
In the mode section, switch on the "Invisible" toggle, name
the Attribute Tag "BP1" and select Break Point 1 as the
insertion point. Then select O.K.
Repeat the process for Break Point 2 and your valve is ready to be saved
as a Wblock. Your valve should look something like this :
Now WBlock the valve to your hardrive.
O.K. Now we've stored the Break Point values as attributes within our
block.
Now comes the difficult part!! How do we retrieve this information?
Easy....
First, open a new drawing and insert the Valve drawing. Just select
"O.K." when the attribute dialog appears. Now type this at the
command line:
(setq edata (entget (setq en (entlast))))
Lisp should return something like this :
((-1 . ) (0 . "INSERT") (5 . "7AE") (100 . "AcDbEntity")
(67 . 0) (8 . "0") (100 . "AcDbBlockReference") (66 . 1) (2 . "VALVE") (10
508.26 476.045 0.0) (41 . 1.0) (42 . 1.0) (43 . 1.0) (50 . 0.0) (70 . 0) (71 .0)
(44 . 0.0) (45 . 0.0) (210 0.0 0.0 1.0))
O.K. we've got the entity data list, but now we need the attribute
data. Type this:
(setq edata (entget (entnext (cdr (assoc -1 edata)))))
You should get something like this:
((-1 . ) (0 . "ATTRIB") (5 . "7AF") (100 . "AcDbEntity")
(67 . 0) (8 . "0") (100 . "AcDbText") (10 518.26 476.045 0.0) (40 . 3.5) (1 ."")
(50 . 0.0) (41 . 1.0) (51 . 0.0872665) (7 . "ITALICT") (71 . 0) (72 . 0)
(11 0.0 0.0 0.0) (210 0.0 0.0 1.0) (100 . "AcDbAttribute") (2 . "IP2") (70 . 1)
(73 . 0) (74 . 0))
Voila, the attribute data list. Now, I just happen to know that the DXF
group code for the attribute insertion point is Code 10. So let's extract
it :
(setq ip1 (cdr (assoc 10 edata)))
Lisp should return the attribute insertion point and it should look
something like this:
(518.26 476.045 0.0)
We would now simply repeat the process for the second break point.
Well that, is basically the heart of the program. We've inserted our
block and we've established our break points. All we need to do now is
break our line.
Here's the full AutoLISP coding for our Auto-Breaking Block:
(defun c:abreak ( / oldsnap bname ip ent1 ent2 ep1 ep2 ang edata ip1 ip2)
(setq oldsnap (getvar "OSMODE"))
;get the current snap
(setvar "OSMODE" 544)
;set snap to intersection and nearest
(setvar "BLIPMODE" 0)
;switch blips off
(setvar "CMDECHO" 0)
;switch command echo off
(setq bname (getfiled "Select Auto-Breaking Block" "" "dwg" 8))
;get the block to insert
(while
;while an insertion point is selected
(setq ip (getpoint "\nInsertion Point: "))
;get the insertion point
(setq ent1 (entsel "\nSelect Line to AutoBreak: "))
;get the line to break
(setvar "OSMODE" 0)
;switch the snap off
(setq ent2 (entget (car ent1)))
;get the entity data of the line
(setq ep1 (cdr (assoc 10 ent2)))
;get the first end point
(setq ep2 (cdr (assoc 11 ent2)))
;get the second end point
(setq ang (angle ep1 ep2))
;get the angle of the line
(setq ang (/ (* ang 180.0) pi))
;convert it to degrees
(setvar "ATTDIA" 0)
;switch off the attribute dialog box
(command "Insert" bname ip "" "" ang "" "")
;insert the block
(setq edata (entget (setq en (entlast))))
;get the block entity data
(setq edata (entget (entnext (dxf -1 edata))))
;get the attribute entity list
(setq ip1 (dxf 10 edata))
;extract the first attribute insertion point
(setq edata (entget (entnext (dxf -1 edata))))
;get the next attribute entity list
(setq ip2 (dxf 10 edata))
;extract the second attribute insertion point
(command "Break" ent1 "f" ip1 ip2)
;break the line
(setvar "OSMODE" 544)
;switch snap back on
);while
(setvar "OSMODE" oldsnap)
;reset snap
(setvar "BLIPMODE" 1)
;switch blips back on
(setvar "CMDECHO" 1)
;switch command echo back on
(setvar "ATTDIA" 1)
;switch attribute dialog boc back on
(princ)
;finish clean
);defun
;;;**********************************************************
(defun dxf (code elist)
(cdr (assoc code elist))
);defun
(princ)
I have created a special folder called "Autobreak" were I store
all my Auto-Breaking blocks. I also include this folder as my default
directory in the 'getfiled' function.
If you would like the source coding for this application plus the sample
Valve drawing, then just click here. |