October 24, 2012
From: Bill Fane
Learning curve tutorial: The AutoLISP routine simplifies an otherwise daunting task.
It was a hot, sunny day. Captain LearnCurve and his beautiful wife were staying at their lakeside summer cottage. They were relaxing between the water ski slopes, lazily watching a great blue heron soar past. The only cloud in the sky had a pointed shape… that’s all!
The subject of this article: point clouds! No, this article will not be about AutoCAD point clouds and how they work, but rather will be a scholarly treatise on how to automatically search through a set of drawings for entities that meet certain criteria.
I repeat: Huh?
It all started with an email from reader Dave Sasko. His problem was that he had a large number of drawing files spread out in a complex folder structure and he needed to find the files containing at least one of the new point cloud features. This article will show you how easy it is to find drawings containing a particular type of entity, or even entities with specific characteristics. For example, if you need to find all the designs containing a 12 inch diameter circle that lives on the “Cake” layer, stick around to see how easy it is.
Where to start
Finding drawings containing specific entities is a very simple 4-step process:
- First, we need to create a trivial AutoLISP program that specifies our search criteria.
- Then we use a good old fashioned DOS command to create a list of all the drawing files in the folders to search.
- We then use Notepad to turn the list of files into an AutoCAD “script”.
- Finally, we run the script in AutoCAD. He opens each file in turn, and the AutoLISP program searches for the desired entities. If found, the file name is appended to the end of a log file, the drawing is closed, and the script continues to open the next drawing. When the script completes, the log file is a simple text file that lists all target drawings.
Needle, meet Haystack
Let’s start with the ACADDOC.LSP file: you can either create it yourself using Notepad or download it from the Cadalyst CAD Tips site. Let’s look for files that contain at least one XLine. If you don’t have one, it’s easy to create a sample or three.
(princ "nEntity Finder by Bill Fane 28 Aug 2012n") ;; This program searches a drawing for the specified entity type and/or properties. ;; If it finds any, it opens a log file and appends the full ;; path and file name to the end of the file. ;; If it doesn't find any it simply moves on without reacting. (if ;; start of IF (ssget "x" '( (0 . "xline") ;;Object type &/or properties to find. ) ) (progn ;; start of THEN (setq FH (open "c://foundfiles.txt" "a") ;; Name & location of log file. ) (write-line ;; write out to the log file... (strcat (getvar "dwgprefix") ;; …path to drawing file, plus (getvar "dwgname") ;; …drawing file name ) FH ) (close FH) (princ "nYes!n") ;; Lets you know it found something ) (princ "nNo.n") ;; ELSE it didn't ) (princ)
Probably the most powerful command of any programming language is the If-Then-Else sequence because it allows the program to make decisions based on the information passed to it. The basic operation is that if certain conditions are met, then do one action, but if they are not met, do something else. Note that the Else can often be omitted; if the conditions are not met, then do nothing.
Here is an example of the if–then relationship at work: A wife sends her programmer husband to the store. “Buy a liter of milk, and if they have eggs, take a dozen.” He comes back with twelve liters of milk. “Why the hell did you buy twelve liters of milk?” she asks. “Because they had eggs,” he replies.
In our case, the condition Si is:
(ssget "x" '( (0 . "xline") ) )
In AutoLISP, the (ssget) (Selection Set GET) is used to get a selection set of entities that meet the specified criteria. the (0. “xline”) the expression tells ssget to create a selection set consisting of all the XLine entities in the drawing.
Now for the tricky part: we don’t really care about specific entities. All we want to know is if there are one or more. If so, a valid selection set is created and the If statement moves on to performing Then operations. Yes (ssget) Return nil (no selection defined), then Else comes into play.
Ok, what if a select set of one or more XLines Is to exist? It’s simple: the program creates a “file descriptor” by opening a log file called “c://foundfiles.txt” in Append mode, concatenates (adds) the path to the current drawing file plus the filename drawing itself, writes this information and appends it to the end of the log file, closes the log file, and continues. If there are no XLines in the drawing, the AutoLISP program simply terminates.
So far so good, but now we need to run the ACADDOC.LSP program in each drawing file. No problem; just copy the ACADDOC.LSP file to a folder that is in the AutoCAD search path. You can find the list of folders AutoCAD looks for when searching for support files by clicking the AutoCAD Application menu (the big red A), then the Options button, then the Files tab and expanding the support file search path. (For best results, put it in a folder at or near the top of the list, or add a new folder and move it up, as AutoCAD looks for support files from top to bottom and uses the first he finds.)
The ACADDOC.LSP file does not normally exist, but AutoCAD still looks for it whenever it opens a drawing file. If it finds it, it loads and executes the program it contains.
You can test it by opening several files, some of which contain XLines and some of which do not. Press F2 after opening each drawing to bring up the AutoCAD text screen and it will include “Yes!” or “No” as the case may be. Now open the log file using Notepad, and presto, it contains the list of drawings that contain one or more XLines!
It could be very tedious to manually open each drawing in turn, so now comes the trickiest. You must know (or you must know an old fart who knows) two good old-fashioned DOS commands.
At the AutoCAD Command: prompt, enter the Shell command. When it asks you “Operating system command:”, just hit enter. You are now faced with an old-style pre-Windows system command prompt. If you don’t want your search to start in the default folder, use the CD (Change Directory) command to navigate to the top-level folder where you want the search to start. For example, to find all folders on network drive J: starting with DataProjects, enter the DOS command:
to switch to the network drive, then
to access the desired folder. Now run the DOS command
DIR *.dwg /s /b > find.scr
Nothing seems to happen for a while, depending on the number of files in the number of folders involved, but eventually the DOS command prompt will return. Enter the DOS EXIT command to return to AutoCAD.
Next, use Notepad to open the find.scr file. It will be located in the folder from which you ran the DIR command in the previous step and will contain a brief listing of each DWG file in all subfolders under the current folder.
It will look like this:
N:DataProjectsdoughnut.dwg N:DataProjectsOrdinate dims.dwg N:DataProjectsTarget.dwg N:DataProjectsWater shutoff.dwg
Now use Notepad’s Edit > Replace function twice, as follows:
Find what: N:
Replace with: open “N:
Find what: .dwg
Replace with: .dwg” close
Your file will now look like this:
open "N:DataProjectsdoughnut.dwg" close open "N:DataProjectsOrdinate dimensions.dwg" close open "N:DataProjectsTarget.dwg" close open "N:DataProjectsWater shutoff.dwg" close
Save the file and exit Notepad. Now back to AutoCAD. Run the Scipt command and navigate to the find.scr file. Select it, then watch in awe as AutoCAD sequentially opens each drawing file in turn in the log file, runs ACADDOC.LSP, and then closes each drawing. Depending on the number and size of files involved, you might want to go for coffee, lunch, go home for the night, or to your lakeside cabin for the weekend.
When you return, the log file c:foundfiles.txt will contain a list of all drawings containing at least one AutoCAD XLine entity.
Now for some crunchy bits
First of all, it doesn’t include any error checking. For example, if AutoCAD opens a file and can’t find the required support file, such as a font file or an xref, everything hangs sickeningly. If this happens, tell AutoCAD to ignore the problem and everything will pick up where it left off.
Then if you run it again it just keeps adding to the log file, even though the file already exists in the log file. The solution is simply to delete the log before each execution of the find.scr file.
To note: The ACADDOC.LSP program runs whenever you open a file unless you delete it, rename it, or move it out of AutoCAD’s search path.
Finally, if you want to modify the ACADDOC.LSP file to change the name or location of the output log file, you must use two slashes as folder delimiters (not the single backslash used by DOS).
And now for the bonus round
You can modify ACADDOC.LSP to search for any type of entity with any properties. For example:
(ssget "x" '( (0 . "circle") (8 . "Cake") ) )
will find any drawing with one or more circles on the layer named Cake. the (number . value) is known as group and is based on AutoCAD’s Drawing eXchange Format (DXF) file format. The item to the left of the dot is always an integer, while the value to the right can be an integer, decimal, or text string depending on the integer to the left. Each entity in the drawing is defined by a series of group codes that specify its type, layer, location, and so on. There are around 500 group codes, but very few will cover most of your needs.
You can easily create searches with multiple filters, all of which must be met to return “true”. For example:
(ssget "x" '( (0 . "circle") (8 . "Cake") (40 . 2.5) ) )
will find all circles on the “Cake” layer with a radius of 2.5 units, but ignore other circles on the same layer if their radius is not 2.5 units.
Conversely, it is not necessary to have an entity type. For example:
(ssget "x" '( (8 . "Cake") ) )
will return “true” if the “Cake” layer contains entities of any type, or “false” if it is completely empty.
In closing, here is a little tip that can help you define your search criteria. Just enter the expression (entget (car (entsel))) at the AutoCAD command prompt, then select an entity. The text screen will now show all group codes and specific values that define the selected object.
And now for something completely different
If you have an older high horsepower two-stroke outboard motor that incorporates oil injection, you must replace the tubes between the tank, oil pump and fuel system as they become brittle. with age and may crack. When you do this, it’s extremely important to bleed the air from the tubes before running the motor, otherwise you could end up spending several thousand dollars on parts and the first two weeks of the summer water ski season doing frantically a total engine rebuild. yourself (which is still much cheaper than buying a new four-stroke engine).