Saturday, April 20, 2013

Cunning plans: How to get Autocad to work smarter?

One of the frequent insults hurled at Autocad is that it is not an intelligent program.

Problems with Xrefs
I have tried to steer my drafting life clear of xrefs, for the reason that when I'm gone, some IT Preventer of Information technology will rename the main network drive or someone else will rename directories.  All this will cause blank drawings to appear!  Having said that, maybe the idea of "relative paths" is a good approach. Of course, if you have the files all in the same directory, then this is not a problem.

Say you have an item, say a magnet box, and this is to be placed in a layout, then the only way to keep any automatic updating is to use the Xref mechanism in Autocad. This means that the item being xreffed in needs to be "pure", that is, it has to be just a 3d model and no more.

This then means that you cannot have things like section planes in that model, or any other extras like 2D sketches.

Organizing your Assembly to go into  a Layout Drawing

Yes, you can organise your magnet box drawing to be a series of layout tabs for each of the parts.

There are problems with this approach though:  You have to have all your parts with distinct layer names so that you can use freezing and thawing on a per viewport basis, and while this is possible, setting it all up seems time consuming.

I have devised a layering system that copes with multi-level layouts. It makes layers like:

LEVEL 1 - FLOOR
LEVEL 1 - INTERIOR WALLS
LEVEL 1- PIPING
LEVEL 1 - BEAMS
....and so on. This seems to work well, and is heavily reliant on lisp routines to make it go.
The advantage is that there is a structure to the layer naming.
 
To tie this all in with the layer names you have to create for the above system is also a pain.

This can be got around by calling layers names like MAGNET BOX LID LEVEL 1, and when the xref turns up in the layout, then the lisp line becomes (command "-layer" "t" "*LEVEL 1*" "") ie it uses the * as wild cards.

Any Other Options? 

One that might deserve some consideration, is to have a "pure" model, in which every item is on layer 0, so that when it arrives in the xref, it picks up the layer it is to be, and appears in the correct colours for that layer. Simple.

To enable parts drawings, this pure model would have all the individual parts (each a separate drawing file) xreffed into it.
The nice thing about this system is that you could have a separate assembly drawing of the magnet box, and any sub-assemblies could be easily arranged. In the assembly drawing you can go ahead and do sections.
OK, so what is the downside?  A great pile of autocad drawing files is what you would end up with, instead of one drawing with heaps of layout tabs on it. Coping with printing out a drawing set is probably not as bad as it seems, as you can use saved sheet sets to deal with this. Your drawing register then becomes a large clerical pain to fill out, that is if you decide to go down that route. To avoid this bureaucracy, an alternative to listing them in a separate register could be to maybe keep them in a directory, labelled say "150905 Magnet Box".  In the drawing register, all you need is one entry:"150905 - Magnet Box". Only the "pure" model, with a file name of 150905.dwg would appear in the main directory.

Saturday, March 30, 2013

Drawing an archimedes screw in Autocad

Recently, a man at my work wanted me to draw the junction of a double screw conveyor. It was a long screw conveyor, and had a hanger bearing in the middle that was causing some trouble.  This was the junction.

In the "olden days" I used to use a 2D lisp routine to draw a screw conveyor.  This was my first request since those days to actually draw a screw.  Usually we just draw the outside casing and this is all you really need, unless you are a manufacturer of screw conveyors.

No worries, I thought, I'll just draw a helix, and sweep a rectangle along the helix. Yes, it is that simple. If you have release 13 that is!  At work I am on release 12 and spent 2 hours trying to persuade Autocad to this.  In the end I googled it.  Humf! It appears no easy "how to do it" is there. The nearest I got was someone drawing an acme screw thread.

After about 2 hours I discovered you could do it, but you had to input in a value for twist of about 30 degrees.

On another subject, my website, bilrocad.com seems in for the chop. At one stage I had advertising on it and thought it might pay it's way.  This was not to be. The people at BlueHost did give me an extra year for free though.

Anyway, here is my method for release 13:

1. Draw a shaft - usually these are from 80NB pipe, ie about 89mm outside diameter, say 3000mm high.





















2. Draw helix. In my example, I used a base and top radius of 123.75mm, 10 turns and a height of 3000mm.


3. Draw a rectangle. I drew one 158.5mm x 10mm so that my outside diameter would end up around 406mm.



















4. Issue the sweep command, pick the rectangle and then pick the helix: Job done!








Thursday, January 3, 2013

Sheetmetal-Pretty Basic

Vanilla Autocad does not have a trick for doing simple folded sheet metal developments.
(Hey, we're only up to Release 18 or so, maybe in release 44....)

When I say simple, I mean a piece of sheet metal with one fold or two folds, both at 90 degrees.

Maybe I am the only draftee on the planet that sometimes does this, but it is always a painfully slow process when I do.

To do this manually, I  draw an end on view as above, using polylines. I then would offset
the inner polyline to create a  neutral axis,  by half the metal thickness. In other words, the "K" factor I was using was 0.5.  Which for steel should have been 0.4.  I only realised this by looking up "sheetmetal developments" on the web, here is a good link, even if it is 1998! (In the link he does something similar, but to my mind, not as useful as my one.)

http://www.oocities.org/wpsmoke/acadsheetmetal/paper.html

The length of the neutral axis polyline is the length of the development.  To get the position of the fold lines, I used to use midpoint snap to put a line on the corner and used it to trim the pline: 
Then it was just a matter of clicking on that pine and checking out it's length on the properties palette, to give me the position of the fold line.

All this horsing around: surely I have better things to do? The upshot is an afternoon spent doing the following Lisp routines, which have not been fully tested by hordes of draftees, (apart from me!). So if you like to try them, make sure you cross check the first few by doing the manual stuff above.

To make sure you can check what you keyed in, a piece of text is generated at the end, and put on Defpoints layer (ie it does not print, but you can see it on the screen).

It uses the layer names "MED" for medium thickness lines, "hid" for hidden lines -ie the fold line , and "dim"
for the dimension lines.  If these layers are not there, it should still work.

(Feed back??? Anyone out there????Hullooooo??) 

A typical output in Autocad looks like this:


Here are the two routines: (cut and paste from here into Notepad.)
(These routines are free)
;Program written by Bill Le Couteur
;Auckland NZ
;Rev 0 date 3 JAN 2013
;THIS PROGRAM DOES ONLY SIMPLE SHEETMETAL BEND OF A 90 DEG BEND - U SHAPED TROUGH-BOTH UPSTANDS EQUAL

(defun  c:DEVU()
(setvar "osmode" 0)
(setq KFactor 0.4)
(setq MetalThickness (getreal "\n Enter Metal Thickness"))
(setq InnerBendRadius MetalThickness)

(setq Length1 (getreal "\n Enter Upstand - Outside Dim"))
(setq Length2 (getreal "\n Enter Middle Section - Outside Dim"))
(setq MiddleSection Length2);;;keep this for later use in text
(setq MiddleSections (rtos MiddleSection))
(setq Length2 (/ Length2 2))
(setq TheWidth (getreal "\n Enter the width"))


(setq NeutralInnerOffset (* KFactor MetalThickness))
(setq NeutralOuterOffset (- MetalThickness NeutralInnerOffset))

(setq NeutralBendArcRad (+ NeutralInnerOffset InnerBendRadius))


(setq Length1Neutral (- (- Length1 NeutralBendArcRad) NeutralOuterOffset))
(setq Length2Neutral (- (- Length2 NeutralBendArcRad) NeutralOuterOffset))

(setq ArcLength (/ (* pi 2 NeutralBendArcRad) 4))

(setq DevLength (+ Length1Neutral Length2Neutral Length2Neutral ArcLength ArcLength Length1Neutral))

(setq HalfArcLength (/ ArcLength 2))

(setq DistanceToFold (+ Length1Neutral HalfArcLength))
(setq FarDistanceToFold (- DevLength DistanceToFold))

(setq TheOrigin (getpoint "\n Pick a point for the development"))

(command "UCS" "n" TheOrigin )

(if (tblsearch "layer" "MED") (command "layer" "s" "MED" ""))
(command "_rectangle" "0,0" (list DevLength TheWidth))

(if (tblsearch "layer" "dim") (command "layer" "s" "dim" ""))
(command "_dimlinear" "0,0"  (list DevLength 0) "0,-50" )
(command "_dimlinear" "0,0"  (list 0 TheWidth) "-50,0" )
(command "_dimlinear" "0,0"  (list DistanceToFold 0) "0,-25" )
(command "_dimlinear"  (list FarDistanceToFold 0)  (list DevLength 0) "0,-25" )
(command "-text" (list DistanceToFold 20) "" "90" "BEND UP 90%%D") 
(command "-text" (list FarDistanceToFold 20) "" "90" "BEND UP 90%%D")
(if (tblsearch "layer" "hid") (command "layer" "s" "hid" ""))
(command "_line" (list DistanceToFold 0) (list DistanceToFold TheWidth) "")
(command "_line" (list FarDistanceToFold 0) (list FarDistanceToFold TheWidth) "")



;;;;;;;;;;;;;;;NOW DOING THE TEXT TO ENABLE CHECKING THE INPUT DATA;;;;;;;;;;;;;;;;;;;;;
(command "layer" "s" "Defpoints" "")
(command "UCS" "W"  )
(setq apt (getpoint "\nInsertion Point for Text: "))
(setq TheText "Data for this development input as follows: ")
(setq MetalThicknesss (rtos MetalThickness))
(setq Length1s (rtos Length1))
(setq Length2s (rtos Length2))
(setq TheWidths (rtos Thewidth))
(setq booText (strcat TheText "\nThickness: " MetalThicknesss "\nUpstand : " Length1s "\nMiddle Section : " MiddleSections "\nWidth : " TheWidths "\nK Factor Used is 0.4"))
(command "UCS" "n" apt )
(command "-mtext" "0,0" "200,-100" booText "") 
(command "UCS" "W"  )
(command "layer" "s" "0" "")
   (princ)
)

 Here is the other Routine:
;Program written by Bill Le Couteur
;Auckland NZ
;Rev 0 date 3 JAN 2013
;THIS PROGRAM DOES ONLY SIMPLE SHEETMETAL BEND OF A 90 DEG BEND ANGLE

(defun  c:DEVL()
(setvar "osmode" 0)
(setq KFactor 0.4)
(setq MetalThickness (getreal "\n Enter Metal Thickness"))
(setq InnerBendRadius MetalThickness)

(setq Length1 (getreal "\n Enter Outer Length 1"))
(setq Length2 (getreal "\n Enter Outer Length 2"))
(setq TheWidth (getreal "\n Enter the width"))


(setq NeutralInnerOffset (* KFactor MetalThickness))
(setq NeutralOuterOffset (- MetalThickness NeutralInnerOffset))

(setq NeutralBendArcRad (+ NeutralInnerOffset InnerBendRadius))


(setq Length1Neutral (- (- Length1 NeutralBendArcRad) NeutralOuterOffset))
(setq Length2Neutral (- (- Length2 NeutralBendArcRad) NeutralOuterOffset))

(setq ArcLength (/ (* pi 2 NeutralBendArcRad) 4))

(setq DevLength (+ Length1Neutral Length2Neutral ArcLength))

(setq HalfArcLength (/ ArcLength 2))

(setq DistanceToFold (+ Length1Neutral HalfArcLength))

(setq TheOrigin (getpoint "\n Pick a point for the development"))

(command "UCS" "n" TheOrigin )

(if (tblsearch "layer" "MED") (command "layer" "s" "MED" ""))
(command "_rectangle" "0,0" (list DevLength TheWidth))

(if (tblsearch "layer" "dim") (command "layer" "s" "dim" ""))
(command "_dimlinear" "0,0"  (list DevLength 0) "0,-50" )
(command "_dimlinear" "0,0"  (list 0 TheWidth) "-50,0" )
(command "_dimlinear" "0,0"  (list DistanceToFold 0) "0,-25" )
(command "-text" (list DistanceToFold 20) "" "90" "BEND UP 90%%D") 

(if (tblsearch "layer" "hid") (command "layer" "s" "hid" ""))
(command "_line" (list DistanceToFold 0) (list DistanceToFold TheWidth) "")



;;;;;;;;;;;;;;;NOW DOING THE TEXT TO ENABLE CHECKING THE INPUT DATA;;;;;;;;;;;;;;;;;;;;;
(command "layer" "s" "Defpoints" "")
(command "UCS" "W"  )
(setq apt (getpoint "\nInsertion Point for Text: "))
(setq TheText "Data for this development input as follows: ")
(setq MetalThicknesss (rtos MetalThickness))
(setq Length1s (rtos Length1))
(setq Length2s (rtos Length2))
(setq TheWidths (rtos Thewidth))
(setq booText (strcat TheText "\nThickness: " MetalThicknesss "\nLength 1: " Length1s "\nLength 2: " Length2s "\nWidth : " TheWidths "\nK Factor Used is 0.4"))
(command "UCS" "n" apt )
(command "-mtext" "0,0" "200,-100" booText "") 
(command "UCS" "W"  )
(command "layer" "s" "0" "")
   (princ)
)
Happy developing!





Wednesday, July 25, 2012

Project Organisation

About one year ago at work I started work on a project to install a new packing machine where I work.

In my usual carefree fashion, I organised one drawing to do this. Even though I had my newly developed lisp routine to turn on the stuff on the ground floor and freeze the levels above, it proved cumbersome, especially as I was unable at the time to use my favourite: SECTIONPLANE. At one stage, I even created a new empty drawing and xreffed the main drawing into it and used 3DCLIP to get a clearer idea of what was going on.

In the beginning, it was "only" a proposal, so all this was not really that critical. All that mattered was "Would it fit, and in what configuration."  Now this is a full on project, things are a lot more critical: you have to know where everything is, and what all clearances are to ensure no surprises on judgement day.

I noticed the engineer in charge did not seem all that happy with the drawings, in that it was hard to visualise some parts due to the fact that some things hide other things, so I have decided to rethink my strategy.

We are now going to have a drawing for each machine, and they will be xreffed into a main drawing which will be mostly just a floor with a reference point in it. Walls and doors will be on one drawing, steelwork on another.

The machine drawings will be in 3D and have all their views, dimensions and  annotations in paper space.

Now I am able to use the sectionplane command, there will be one drawing that shows sections, by xreffing in the main drawing to it.

Saturday, June 23, 2012

Everybody draws Process and Instrumentation Drawings...don't they?

This just goes on and on.  Just when I thought I was nearing half way, the "man" said to me:
"Bill, of course you are doing a Bill of Material for every drawing?"
After picking myself up off the floor after a fainting attack, I replied:
"This will take me centuries!"
Fortunately, I had sort of prior knowledge of this (I appear to filter out unwanted information),
so I had devised a block named "TAG" for valves, motors and so on, and one called "INSTRUMENT" as explained in my March 6th 2012 blog.

Writing a lisp to collect all the tag ones and list them in a text file was pretty easy and went well. You might be asking why did I not use Eattext, a newish command to do exactly this? It is OK, but involves lots of button pressing dialog box travelling.

No, I wanted a one button approach.  Silly me. Turns out my dynamic block is a nasty little beast.  Do it as per the tag system and it makes a mess of the count. 

Searching the net showed me that there are really clever lisp programmers out there, but none had written exactly what I needed.

One came close, a man called Doug Broad, who put up a bare bones solution, using Visual Lisp.

It turns out that Visual Lisp extends ordinary lisp, and allows you to solve such a problem as this.

To use visual lisp in a lisp routine, just type: (vl-load-com).  After much frustration, this routine seems to work:
This is a scrap from a typcial P & ID, the instruments are the ones in bubbles.You can see there are quite a few non-essential lines, and maybe it is not done in slick elegant manner, but it it is relatively easy to follow.

Here is the routine:

;Program written by Bill Le Couteur
;Auckland NZ
;Rev 0 date 24 June 2012
;This program EXTRACTS ALL THE BLOCKS CALLED TAG AND INSTRUMENT
;AND CREATES A TEXT FILE WITH THE ATTRIBUTES

(defun  c:PIDE()

;;;this file is the LISTING file
   ;;;;this makes sure file is empty
   (setq scrfile ( open "C:/Bilro/Bilro4/LISTING.TXT" "w"))
   (close scrfile)

 (setq scrfile ( open "C:/Bilro/Bilro4/LISTING.TXT" "w"))

(setq count 0)

 (setq SS1 (ssget "X" (list '(0 . "INSERT") (cons 2 "TAG"))))

(setq no_of_entities ( sslength ss1))

(while (/= count no_of_entities)
  (progn
(setq en (ssname ss1 count))
(setq ed (entget en))
(setq the_attrib (entget (entnext en)))
(setq the_tag (dxf 1 the_attrib))
(print the_tag)
(write-line the_tag scrfile)

(setq count (+ count 1))
);end progn
);end while

;;;;;;;;;;;;;;;;;;;;;;;;;NOW TO FIND THE DYMNAMIC BLOCKS CALLED "INSTRUMENT";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(vl-load-com)
        (setq ss2 (ssget "_X" '((0 . "INSERT"))));;;ESSENTIAL-FIND ALL THE BLOCKS FIRST!!!!!!
    (setq no_of_entities (sslength ss2))
    (setq count 0)
    (setq innercount 0)

    (print no_of_entities)

    (while (< count no_of_entities)
         (progn
        (setq obj (vlax-ename->vla-object (ssname ss2 count)))
               
        (setq itsrealname (vla-get-Name obj))
        (setq itseffectivename (vla-get-EffectiveName obj))

        ;(print obj)
        ;(print itsrealname)
        ;(print itseffectivename)
        ;(if (eq itseffectivename "INSTRUMENT")(PRINT "HELLO THERE"))
                (setq en (ssname ss2 count))
                (setq ed (entget en))
  
                ;(print ed)


;;;;;;;;;;INNER WHILE LOOP::::::::::::::::::::::::::-only if its name is "INSTRUMENT"!
(if (eq itseffectivename "INSTRUMENT")
   (progn
     (while  (< innercount  2)
      (progn  

         (setq en (entnext en))
         (setq ed (entget en))

       
           
         (if (eq innercount 0)
        (progn
            (setq atag (dxf 1 ed))
            ;(print atag)
        );end little if progn
         );end little if

        (if (eq innercount 1)
        (progn
                    (setq the_no (dxf 1 ed))
            ;(print the_no)
            (setq instrument_tag (strcat atag the_no))
            (write-line instrument_tag scrfile)
            ;(print instrument_tag)
            );end little if progn
         );end little if
         
   
    ;(print count)
    ;(print innercount)
   
       
   
    ;(print ed)
    (setq innercount (+ innercount 1))
   
     );end while progn
    );end while /= sequend

);END IF PROGN
);END IF

;;;;;;;;;;INNER WHILE LOOP::::::::::::::::::::::::::




                (setq innercount 0)
                (setq count (+ count 1))
         );end while progn
         );end while







    (close scrfile)

   (princ)
)


(defun dxf(code elist)
  (cdr (assoc code elist))     ;Finds the association pair, strips 1st element
);defun


Saturday, April 14, 2012

Process and Instrumentation Diagrams (PIDs)...but wait ...there's more!


Hmfff.....looks like I was wrong thinking 1.5mm high text was a good idea.

It so happened that one of our electrical engineers has just had an eye operation and was having an awful time trying to read my drawings.

I realised they would have to be changed to 2mm high, which a huge nuisance as I have done quite a few drawings.

Just to add to the fun, it appears that the requirement is for each sheet to show mainly just one item, so a drawing might only have one tank, with it's associated piping and pumps. So the emphasis is still on systems, just at a finer level.

The drawings I had done were not wasted, as they became the detailed PROCESS FLOW DIAGRAMS. Some upside to this as I have a bad habit of trying to squeeze too much onto one drawing usually.

I have started on a lisp routine to deal to errant drawings: it is called FIX.lsp. When it is up and running I will post it.

In the meantime, in a rush of enthusiasm that has just evaporated, I have just gotten the skeleton of a routine together that should make PID drudgery a little easier.

The idea of the routine, called ADTAGS.lsp, is that you have done all the graphical elements of your drawing, that is you have drawn all the valves and pipelines in, and you now wish to add tags to all the items in the drawing. For instance you may have 3 manual valves, and you want to label them with tags, HV001,HV002 and HV003, as per the picture above.

Here is the routine, which is obviously far from finished:

;Program written by Bill Le Couteur
;Auckland NZ
;Rev 0 date 14-4-12
;This program adds tag numbers to a bunch of blocks
;only works for blocks named "VALVE MANUAL" at the moment

(defun c:ADTAGS()
(setq count 0)
(setvar "attdia" 0); turns off the dialog box you get when issuing ate commmand

(setq ss1 (ssget "X" '(( 0 . "INSERT")( 2 . "VALVE-MANUAL")) ))
;gets a selection set of the whole drawing, filtering for the block we want

(setq the_no_of_members(sslength ss1))
;how many members in the selection set?

;;;;;LOOP THROUGH THE SELECTION, GETTING POSITION INFO AND USING THIS TO
;;;;;SET THE INSERTION POINTS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


(while (< count the_no_of_members)
(progn
(setq en (ssname ss1 count))
(setq edata (entget en))
(setq theposn(cdr(assoc 10 edata)))
(setq the_x (car theposn))
(setq the_x ( - the_x 5))
(setq the_y (cadr theposn))
(setq rot (cdr (assoc 50 edata)))
(if (eq rot 0)(setq the_tagy (+ the_y 4)))
(if (/= rot 0)(setq the_tagy (- the_y 1.5)))
(if (/= rot 0)(setq the_x ( + the_x 9)))
(setq counts (itoa count))
(if (eq rot 0)(setq the_tag (strcat "HV00" counts)))
(if (/= rot 0)(setq the_tag (strcat "HV00" counts)))
(command "-insert" "tag" (list the_x the_tagy) "1" "1" "0" the_tag)

(setq count ( + count 1));add one to the counter to keep the loop going

);end while progn
);end while

(setvar "attdia" 1);turns on the dialog box you get when issuing ate commmand

(princ)
)

Friday, March 30, 2012

Rough Visualising of ideas

We have a man at our work who has an infectious enthusiasm for new ways of creating electricity.

Much fun has been had proposing all sorts of wild schemes involving kites and so on. I have a digital camera that can take movies, so I decided to experiment with it to present one of my ideas. A patent search revealed some similar ideas, but not precisely this one. I'm not sure on the business with patents, but I think that seeing as this idea is now out in the wild, no one can patent it.

It would be nice if someone with a bit of money and enthusiasm picked it up and ran with it.

The idea is very simple. You have a series of windmills, held aloft by a balloon, but they are better than a similar size at ground level, because the winds are faster the higher you go.