Controlling the Machine

  • Coinciding with the acquisition of VIA Development, Nate joined Autodesk in March of 2003 after a decade stint as an entrepreneur following a two-decade stint as a controls engineer and software applications developer at Owens-Corning. Nate is now the lead product architect for AutoCAD Electrical. He loves this stuff.

    About Nate

Latest Post

  • Flagging source/destination wiretype mismatches - AutoCAD Electrical
    December 21, 2008 10:22 PMby Nate Holt

    It seems to not be that hard to end up with some mismatches between wire types jumpting from one drawing to another. Here's a little tool that may help highlight these mismatches.

    The utility is written in AutoLISP and makes a handful of calls into the AutoCAD Electrical API. It operates wholly on the current project's "scratch database" file. It first queries the database's SIGS table and pulls in a list of all of the source / destination signal arrows currently found in the project. This data includes the arrow symbol handle, drawing index code, and the assigned SIGCODE attribute value (used to match up source to destinations). Then it scans the WDATA table. This table carries the current state of all of the project's wire connections.

    Each wire connection record includes the connected component's handle, drawing index, and the layer of the connected wire. So all the utility needs to do is use the first list of data, the SIG table data, as a filter against all of the wire connections in the project. It finds and groups all wire connections that have a common SIGCODE attribute value. Within each group, If there are two or more wiretype layers represented for the common SIGCODE value, it flags this as a "wire type  mismatch" condition.

    Here is sample output: For example, it shows that Source signal "M413 AUX N.O." is linked to wire type layer "RED_14AWG". But the Destination end where this wire jumps to is marked as being wire type layer "RED_18AWG". 

    If you'd like to give this a try, please download the utility here:

    files/23201_23300/23261/file_23261.lsp - rename to audit_sig_layers.lsp

    To use:

    1. Select your project to be the "active" project

    2. APPLOAD attached AutoLISP file

    3. Type audit_sig_layers [Enter] at the "Command:" prompt

    That should do it. The utility should output a list of any mismatches found. This list appears in the command window and it also written out to a text file.

    Please feel free to adjust this utility. It is straight AutoLISP. Should be fun to do!

     

    2 Comments | Add CommentIn Controlling the Machine >

Previous Post

  • Quick, Project-wide SYSVAR report - AutoCAD Electrical
    December 17, 2008 08:17 AMby Nate Holt

    You're ready to ship out the 500-page drawing set. You forgot that you need to confirm that certain key AutoCAD system variables are preset to the customer's requirements. Are you looking at hours or minutes?

    With AutoCAD Electrical, you might be able to use the AutoLISP utility (below) to generate a report on all drawings in a selected folder. I tested this on AutoCAD Electrical 2008 and 2009 and it seems to give good results. You can download the sample utility here:

    files/23001_23100/23061/file_23061.lsp - rename it to lib_sysvar_list.lsp

    To test:

    1. APPLOAD above file

    2. Type lib_sysvar_list.lsp [Enter] at command line.

    3. This dialog appears. Browse to the target folder to report on.

    4. Then, in the command window, enter a semi-colon delimited list of the SYSVARS you want to report on. Let's say you want to list the drawing's current selected layout tab, current layer name, OSnap setting, and current text style:

    Command: LIB_SYSVAR_LIST [Enter]
    File count:9
    Enter SYSTEM VARIABLES to extract. Enter ";" delimited, no spaces.
    Sysvars:
    CTAB;CLAYER;OSMODE;TEXTSTYLE [Enter]

    5. That should do it. The utility processes each drawing (without opening it in AutoCAD) and spits out the information to the command window and to an ASCII text file report.

    There it is... looks like drawings "demo04" and "demo02" need some attention. All the other drawings are set per customer's requirements.

    How does this thing work?

    Here is the utility's code. There are a couple API calls in there specific to AutoCAD Electrical, so this thing will not work "as is" if the product is not present. A key call is shown highlighted. It attempts to read the AutoCAD drawing without opening it in the graphics window.

    ; 16-Dec-08 NEHolt created
    (defun c:lib_sysvar_list ( / sysvar_lst x path str ff val dlst
                                   dnam sysvar fout)
      (setq sysvar_lst nil)
      (setq x GBL_WD_BASELIBS) ; point at AutoCAD Electrical base symbol library
      (if (not x)(setq x ""))
      ; Allow user to browse to target library folder
      (setq path (c:wd_pview_folder "Select symbol lib folder to process" x))
      ; Make sure all slashes are "back slashes"
      (if path (setq path (wd_4_all_slashes_backward (strcase path T))))
      (if (AND path (/= path "")) ; user select some folder & no "Cancel"
        (progn ; get list of all ".dwg" files in this folder
          (if (not (setq dlst (wd_1a_dir_filelist path "*.dwg" nil 1)))
            (princ "\nNo files found in this folder.")
          ; ELSE
            (progn ; okay to continue
              (princ "\nFile count:")(princ (length dlst))(princ "\n")
              (princ (strcat
                        "Enter SYSTEM VARIABLES to extract. "
                        "Enter \";\" delimited, no spaces.\n"))
              (setq str (getstring "Sysvars:" T))         
              (if (AND str (/= str ""))
                (setq sysvar_lst (c:wd_delim_str_to_lst str ";"))
              )
              (if sysvar_lst
                (progn ; okay to continue
                  ; Open a text file to save results
                  (setq fout (open "c:/sysvar.rep" "w"))
                  (write-line path fout) ; output the "path" to the report file
                  (foreach dnam dlst
                    ; Process each drawing
                    (princ "\n")
                    ; Open dwg file using AutoCAD Electrical special function
                    (setq ff (wd_dbx_open dnam "r"))
                    (if ff
                      (progn
                        (foreach sysvar sysvar_lst                 
                          ; Read the target system variable name
                          (setq val (wd_dbx_getvar ff sysvar))
                          (princ sysvar)(princ "=")(princ val)(princ " ")
                          ; push out to the output file
                          (princ sysvar fout)
                          (princ "=" fout)
                          (princ val fout)
                          (princ " " fout)
                        )
                        ; Attach drawing name to end of each line of display
                        (princ " Dwg=")(princ (cadr (c:wd_split_fnam dnam)))
                        ; put out to the output file
                        (princ " Dwg=" fout)
                        (princ (cadr (c:wd_split_fnam dnam)) fout)
                        (princ "\n" fout)
                        (wd_dbx_close ff)
                        (setq ff nil)
      ) ) ) ) ) ) ) ) )
      (if fout
        (progn
          (close fout) ; close the report file
          (setq fout nil)
          (princ "\nReport file= c:\\sysvar.rep")
      ) )
      (princ)
    )

    Disclaimer: this seems to work okay in AutoCAD Electrical 2008 and 2009, but suggest you run it against a COPY of your drawing set. I did not try it in earlier versions.

    0 Comment | Add CommentIn Controlling the Machine >

  • Parametric PLC Database Find/Replace - AutoCAD Electrical
    December 15, 2008 08:55 PMby Nate Holt

    There are 4000 or so different PLC modules carried in the Access database shipped with AutoCAD Electrical. What if you want to adjust some annotation default across the whole library? This little AutoLISP utility may help!

    For example, the default tag-ID annotation format is "PLC%N" where the "%N" part is the next unused sequential or the current drawing line reference location. But what if you want to embed the sheet number in the default tag-ID? You want the default tag-ID format to be "PLC-%S-%N".

    Would be nice to just have some kind of quick Find/Replace tool to operate on the Microsoft Access database file "ace_plc.mdb".

    This tool might do it. It makes use of a handful of calls supplied with the AutoCAD Electrical API and is set up to operate on the ace_plc.mdb Access database file. This utility is in two pieces:

    A small AutoLISP "DCL" dialog definition file

    files/23001_23100/23031/file_23031.dcl - rename ace_plc_mdb_find_replace.dcl and put somewhere in your ACAD search path.

    A small AutoLISP ".LSP" program file

    files/23001_23100/23041/file_23041.lsp - rename ace_plc_mdb_find_replace.lsp and put somewhere in your ACAD search path.

    To Use:

    1. VERY IMPORTANT - make BACKUP of your ace_plc.mdb before you launch this utility ( ! ! ! ! ! )

    2. APPLOAD the ".lsp" file above

    3. Type this at the "Command:" prompt:

     ace_plc_mdb_find_replace [Enter]

    4. This dialog should pop up:

    5. Make selection as described in the illustration above. Enter the "Find" and "Replace" substrings and then hit OK.

    That should do it. Give it a try, but be careful... MAKE BACKUP OF YOUR FILE before you start.

    1 Comment | Add CommentIn Controlling the Machine >

  • Auto title block update using "Diesel" Fields - AutoCAD Electrical
    December 13, 2008 10:55 AMby Nate Holt

    The Challenge

    A new AutoCAD Electrical user has a spot in his title block where he wants to show the last three characters of the current layout tab name. Having this come in automatically would be awesome. He asked if he could somehow make use of the AutoCAD "Field" concept and somehow have this information automatically fill into this spot on his title block.

    A field is an updatable text entity that is set up to display variable data. A field can be embedded into a block along with attribute definitions. The field is linked to some data element. There are lots of possibilities. Here is the field definition dialog box with the possible, linkable field names in the left-hand column.

    The currently selected layout tab name is stored in the AutoCAD "system variable" called CTAB. It looks like we could easily create a "Field" that links to this system variable (shown above). This field would then automatically update to show whatever tab is currently selected. So when we create our title block, along with ATTRIBUTE definitions we push into the block, we would also type FIELD at the AutoCAD command prompt and add in a field text entity tied to "SystemVariable" --> "ctab" as shown above. It will automatically update to whatever layout tab name is current. Cool... but...

    The Complication

    We have a problem. We don't want the whole layout name. We just want the last three characters of this layout name to show up in this title block field. If we could embed an AutoLISP expression into our field, we could strip out all but the last three characters. But an AutoLISP expression is not one of the field-link options in the dialog.

    Diesel to the Rescue

    Wow! Looks like a Field can be linked to a "Diesel" expression!

    I have to admit that it's been a very long time since I played around with this vintage Diesel stuff that's been in AutoCAD forever. It seems to parallel AutoLISP but with a goofy syntax (as if AutoLISP syntax doesn't seem goofy too, at first!).

    To get the current select layout tab name, it looks like Diesel supports the "getvar" function to get the system variable "CTAB" which carries the full layout tab name.

    Then we need to look at the length of this layout name and just pull out the last three characters. Assuming the layout name could be variable length, we'll need to use the Diesel function "strlen" to get the length, "substr" to get just a part of the overall layout name string, and the Diesel "-" subtract function to calculate where our substring is to begin to get just the last three characters.

    The Solution

    After some trial and error, I finally figured out the right syntax for the title block's field definition. Here it is...

    It Works!!!

     

     

     

    0 Comment | Add CommentIn Controlling the Machine >

  • Auto-create Project-specific Catalog Lookup Database - AutoCAD Electrical
    December 6, 2008 03:42 PMby Nate Holt

    Project is finished but you need a parts catalog lookup database file that has just the parts used in the project. Maybe this needs to be part of the deliverables. But stripping out tens of thousands of records from a copy of the huge AutoCAD Electrical "default_cat.mdb" file is not an attractive activity.

    No problem. Here's a tool to automatically create the file.

    (This was to be the 5th example in the Autodesk University presentation I gave last Wednesday... a bit late, but here it is.)

    Program flow is this:

    1. Makes a project-specific named copy of the existing default_cat.mdb and puts it in the same folder as your project's ".wdp" file.

    2. Blanks out all part tables

    3. Opens your active project and queries the scratch database. Collects all used catalog part number assignments.

    4. Now processes each one. Queries the default_cat.mdb and if a matching record found (plus any ASSYCODE records), copies them over into the empty, project-specific copy.

    Seems to work. Download here:

    files/22701_22800/22761/file_22761.lsp - (ACE2009 only!) rename as project_cat.lsp

    UPDATE: this revised version should work for ACE2008 and ACE2009 (ACE2007 - did not test):

    UPDATE#2 - found some issues. This one should work better, either 2008 or 2009:

    files/24501_24600/24581/file_24581.lsp - (ACE2008 or ACE2009) rename as project_cat.lsp

    To use:

    1. Make the target project the "active" project.

    2. APPLOAD above file

    3. Type project_cat [Enter] at AutoCAD command line prompt.

    File should be created in a minute or so.

    It will still be "big". I think if you open it in Microsoft Access and hit the "compress" tool, it will purge out all of the deleted stuff and might slim down to a smaller file size.

    UPDATE: original version only set up to work on ACE2009. Revised to work on ACE2008 and possibly earlier. See above.

     

     

     

    0 Comment | Add CommentIn Controlling the Machine >

  • Enhancing Circuit Builder with User-defined Functions - AutoCAD Electrical
    December 2, 2008 04:53 PMby Nate Holt

    Thanks to Autodesk's Pat Murnen for this idea...

    Let’s say that you are working together with an instrumentation engineer on a fairly big project. You’re doing the electrical controls and he is doing what he does. He supplies you with an Excel spreadsheet listing the major equipment that you have to power like motors and pumps and stuff. His spreadsheet might look like this:

     

    For the motor circuits, you want to run the Circuit Builder command to pop in the 3-phase schematic power circuits. But the motor tag, description, and equipment spec horsepower values then need to be manually pulled from the spreadsheet and annotated on to the schematic’s motor symbol.
    Painful.
    Wouldn’t it be cool if, right inside of Circuit Builder, we could pop up this Excel data and just “pick” on the row of data and have it automatically get pushed on to the circuit’s motor symbol?
    Let’s do it. Here’s one strategy…
    1.    Create a little AutoLisp utility that reads the P&ID data spreadsheet, displays the data in a pick list dialog. User picks a row of data. The little AutoLisp utility then pushes the picked row’s data out to the last electrical symbol that was inserted into the drawing.
    2.    Modify the Circuit Builder spreadsheet file, “ace_circuit_builder.xls”, to include a “call” to our little AutoLisp utility at a strategic point in the spreadsheet just AFTER the motor symbol is inserted. The AutoCAD "handle" of the motor symbol should be accessible from a global Lisp variable "#hdl_list" that Circuit Builder maintains for a short time after each component inserts. The call to our utility will tie in to this global to grab the motor symbol's handle and then push the picked P&ID data out to it.

    Step 1 – The little AutoLisp utility

    This will be in two parts: A) a medium-sized AutoLisp program saved in a text file that we will name “pid_pick.lsp”, and B) a small text file that defines the basics of the pick list “dialog” that will display the spreadsheet data. We’ll will name this file “pid_pick.dcl”.

     

    Here is the program part, file pid_pick.lsp followed by the dialog definition file pid_pick.dcl
    ; ** 01-Dec-2008 - sample program based on example created by Autodesk's Pat Murnen
    ; ----------- P I D _ P I C K . L S P ------------
    ;
    ; This function called from within Circuit Builder when a motor symbol has just been inserted.
    ; It opens an Excel file containing data extracted from a drawing such as a P&ID. This data is
    ; displayed in a small dialog. User picks an entry in this dialog and hit's OK. Selected entry's
    ; data is then pushed out to specific TAG1 and RATINGx attributes on the just-inserted motor
    ; symbol.
     
    (defun c:pid_pick ( xlsfnam / cancel dcl_id dclnam dsplst ff fields fldnamstr
        fnam lst recs rtrn xlshdl en tabnam xlsfnam ben newlst data x)
       
     ; NOTE: do NOT declare #hdl_list as a local variable here. It is a global Lisp variable that
     ; is set by Circuit Builder's "insert component" API call.                        
     (setq rtrn nil)
     (setq recs nil)
     (setq ben nil)
     (setq fnam nil)
     
     ; First, test to see if Circuit Builder has just inserted a component. The global "#hdl_list"
     ; should be non-nil and should contain a valid handle as the first element of the list.
     (if (OR (not #hdl_list) (not (car #hdl_list)) ; #hdl_lst does not exist
              (not (setq ben (handent (car #hdl_list))))) ; big assumption that first block is our target
        (progn ; problem, no global exists or doen't carry valid handle
          (princ "\nProblem: could not find handle of recently inserted component\n")
        )
     ; ELSE
        (progn ; Have what appears to be the recently inserted component. Okay to continue.
          ; Step #1 - open up the spreadsheet containing the P&ID data. Read in the data and
          ;           display in a pick list.
          ; read in the spreadsheet with the extracted P&ID data
          (if (not xlsfnam)(setq xlsfnam (getfiled "P & ID Extracted Data Spreadsheet" "pid_extract.xls" "XLS" 0)))
     ) )
     (if xlsfnam
        (progn ; A spreadsheet filename identified. Try to open it and read it in.  
          (if (/= (strcase (substr xlsfnam (- (strlen xlsfnam) 2))) "XLS")
            (setq xlsfnam (strcat xlsfnam ".xls"))
          ) 
          (if (not (setq fnam (findfile xlsfnam))) ; look for the XLS file in normal Acad path list
            ; Not found. Keep looking.
            (setq fnam (findfile (strcat GBL_wd_usr xlsfnam))) ; look for it in AcadE "User" folder
          )
          (if (not fnam)
            (progn ; could not find the target spreadsheet file
              (princ "\nCannot find ")
              (princ xlsfnam)
            )
          ; ELSE 
            (progn
              ; open it and read it in
              (if (AND (setq xlshdl (wd_mdb_gethandle 2)) ; get next file handle
                       (setq ff (wd_mdb_Open xlshdl fnam "Excel 5.0;HDR=YES")) ; open as Excel file
                       (setq tabnam (wd_mdb_GetTabNames xlshdl)) ; list of sheet names
                       (setq tabnam (car tabnam))) ; use first or only sheet defined in xls file
                (progn
                  ; Excel file exists and was able to be opened. Read in the list of
                  ; column field names pulled from the target sheet.
                  (setq fields (wd_mdb_GetFieldSpecs xlshdl tabnam))
                  ; Assuming columns in the sheet are in the expected order ( ! )
                  (if fields
                    (progn ; only pulling out 2nd (Tag) and 4th (Description) fields and 6th (Rating1)
                      (setq fields (car fields))
                      (setq fldnamstr (strcat (car (nth 1 fields)) "," (car (nth 3 fields)) "," (car (nth 5 fields))))
                    )
                  ; else
                    (setq fldnamstr "Tag,Description,Equipment Spec")   
                  )
                  ; Read in all the data from the first sheet of the spreadsheet
                  (setq recs (wd_mdb_GetRecs xlshdl tabnam fldnamstr "" ""))
                  (wd_mdb_Close xlshdl) ; close the spreadsheet file
                  (setq xlshdl nil)
                  ; Now process the returned spreadsheet data dump
                  (setq dsplst '())
                  (if recs
                    (progn ; some spreadsheet data returned
                      ; clean up the returned data. It consists of dotted pairs with first part
                      ; being a copy of the column name. Strip off the column names leaving just
                      ; a list of sublists of row data.
                      (setq data recs)
                      (setq recs nil)
                      (foreach lst data
                        (setq newlst '())
                        (foreach x lst
                          (setq x (cdr x))
                          (if (= x " ") (setq x ""))
                          (setq newlst (cons x newlst))
                        )
                        (setq recs (cons (reverse newlst) recs))
                      )
                      (setq recs (reverse recs)) ; put back into original order
                      ; Format the cleaned spreadsheet data into a display list of data
                      (foreach lst recs
                        ; display format is different order than actual data. It needs to be a
                        ; list of concatenated text strings with TAB characters appropriately
                        ; positioned.
                        (setq dsplst (cons (strcat (car lst) "\t" (nth 2 lst) "\t" (cadr lst)) dsplst))
                      )
                      (setq dsplst (reverse dsplst)) ; restore original order
                  ) )          
                  ; Look for dcl file of same name, open if found.
                  (setq cancel nil)
                 
                  (if (AND dsplst (setq dclnam (c:ace_find_file "pid_pick.dcl" 16)))
                    (progn ; 16 bit set =display error dialog if file not found
                      (setq dcl_id (load_dialog dclnam))               
                      (if (new_dialog "main_select" dcl_id)
                        (progn ; successfully found and opened the DCL file and dialog definition
                          (set_tile "main_title" "P & ID Equipment List")
                          ; Push the spreadsheet's formatted data list out to the display
                          (start_list "dsplst")
                          (mapcar 'add_list dsplst)
                          (end_list)
                          ; Set up to allow user to select a row of data from the display list
                          (action_tile "dsplst" "(setq rtrn (nth (atoi $value) recs))")
                          (action_tile "cancel" "(setq cancel 1)") ; "Cancel" button
                          (start_dialog)
                          (unload_dialog dcl_id) ; user exits dialog with OK or cancel
                  ) ) ) )
                  (if (AND (not cancel) rtrn)
                    (progn ; user didn't cancel out of dialog, okay to continue
                      (if (AND (car rtrn) (/= (car rtrn) ""))
                        (progn ; returned non-blank tag-ID value
                          (c:ace_mod_tag_attrval ben (car rtrn) nil) ; push tag-ID out to TAG1/TAG2
                          ; Mark the tag as "fixed"
                          (c:ace_tag_fixed en 1 nil)
                      ) )
                      ; Push data out to DESC1 and RATING1 attributes
                      (if (AND (cadr rtrn) (/= (cadr rtrn) "")) (c:wd_modattrval ben "DESC1" (cadr rtrn) nil))
                      (if (AND (nth 2 rtrn) (/= (nth 2 rtrn) "")) (c:wd_modattrval ben "RATING1" (nth 2 rtrn) nil))
       
                  ) )
     ) ) ) ) ) )             
     (princ)
     
    ... and here is the small dialog definition file, pid_pick.dcl :
     
    main_select : dialog
     {
     key="main_title";
     :text{label="Select motor or equipment number from this list";}
     :list_box{key="dsplst";width=75;height=17;tabs="20 30";allow_accept=true;}
     ok_cancel;
     }
     

    Step 2 – Add reference into the ace_circuit_builder.xls spreadsheet file.

     
    Once the above two files are saved to some folder that is in the AutoCAD support path list, you’re ready to add a reference to this utility, (c:pid_pick nil), to the spreadsheet.
    The key is to insert this reference at the point just after the motor symbol inserts.
     

    Here is the sheet for the “horizontal” three-phase circuit definition. The entry that triggers the motor to insert is shown here in the "H" column of the spreadsheet:

    Then the “I” column has two API calls: (c:ace_cb_anno…) to do some annotation and (c:ace_cb_save…) to save the resulting motor’s tag-ID to memory for potential later use (for doing wire numbers, for example).

     

    The call we want to insert will be the main program’s name from the lisp file above. It would look like this: (c:pid_pick nil) where the “nil” part means that we are not passing a pre-defined pid extract file name to the function.
     

    So, let’s edit the Excel spreadsheet for the “3PH_H” sheet and change this cell to look like this:

      

    Save the edited spreadsheet.
     
    Now let’s test.
    1.    Make sure that pid_pick.dcl is saved into a folder that is included in the ACAD support path.
    2.    Appload the pid_pick.lsp file
    3.    Launch Circuit Builder and insert a horizontal 3-phase motor circuit.
    4.    Hopefully, as the circuit builds, it will get to the point where our new lisp API call is embedded. You should get prompted to browse to the P&ID data extraction spreadsheet.
    5.    The utility reads the spreadsheet and pops up a pick-list dialog:

     

    Pick an entry and hit OK.
     

    The utility will push the above row’s values out to the motor symbol as circuit builder creates the three-phase motor circuit ( ! ).

    Here are the sample files if you'd like to try out Pat's idea. You'll need to manually edit your ace_circuit_builder.xls file to include the call to (c:pid_pick nil).

    files/22601_22700/22621/file_22621.xls - rename pid_extract.xls

    files/22601_22700/22631/file_22631.dcl - rename pid_pick.dcl and put into an ACAD support folder

    files/22601_22700/22641/file_22641.lsp - rename pid_pick.lsp and put into an ACAD support folder

     

     

     

    2 Comments | Add CommentIn Controlling the Machine >

Subscribe to Blog

Want to keep up with the latest? Subscribe to the RSS feed today.

RSS

Categories

All

Blog Roll

AUTODESK MANUFACTURING COMMUNITY

Ellipsis
The official Autodesk Manufacturing Tech Evangelist blog
Under The Hood
Brian Schanen on Vault, Productstream, and more
In the Machine
Garin Gardiner hosts the official blog of the Inventor Product Team
Controlling the Machine
Archive of Nate Holt's AutoCAD Electrical posts

RECOMMENDED

Being Inventive
The official support blog for the Autodesk Inventor product line
Between the Lines
Shaan Hurley's AutoCAD Blog
It's Alive in the Lab
Scott Shepherd's Lab's Blog
Beyond the Paper
Volker Joseph's DWF Blog
Lynn Allen's Blog
Staying current with AutoCAD and Autodesk

PEER

AutoCAD Electrical Etcetera
Nate Holt shares AutoCAD Electrical tips and tricks.
Autodesk Manufacturing Northern European
The official blog for the Autodesk Northern Europe Manufacturing Technical Team.
Sean Dotson's Site
Sean Dotson's mCAD Tutorials, Forums, Admins & more
The Autodesk Informer
Helpful sites, tutorials, and industry news
CAD Professor
Inventor, Inventor LT, and AutoCAD news and updates.

Send to a Peer

You must login to share pages.

Feedback

Tell us what you think of the site.

Send Feedback