3D printing is all the rage these days. PADT has been involved in what should be called Additive Manufacturing since our founding twenty years ago. So people in the ANSYS world often come to us for advice on things 3D Printer’ish. And last week we got an email asking if we had a way to convert a deformed mesh into a STL file that can be used to print that deformed geometry. This email caused neurons to fire that had not fired in some time. I remembered writing something but it was a long time ago.
Fortunately I have Google Desktop on my computer so I searched for ans2stl, knowing that I always called my translators ans2nnn of some kind. There it was. Last updated in 2001, written in maybe 1995. C. I guess I shouldn’t complain, it could have been FORTRAN. The notes say that the program has been successfully tested on Windows NT. That was a long time ago.
So I dusted it off and present it here as a way to get results from your ANSYS Mechanical or ANSYS Mechanical APDL model as a deformed STL file.
UPDATE – 7/8/2014
Since this article was written, we have done some more work with STL files. This Macro works fine on a tetrahedral mesh, but if you have hex elements, it won’t work – it assumes triangles on the face. It also requires a macro and some ‘C’ code, which is an extra pain. So we wrote a more generic macro that works with Hex or Tet meshes, and writes the file directly. It can be a bit slow but no annoyingly slow. We recommend you use this method instead of the ones outlined below.
Here is the macro: writstl.zip
The Process
An STL file is basically a faceted representation of geometry. Triangles on the surface of your model. So to get an STL file of an FEA model, you simply need to generate triangles on your mesh face, write them out to a file, and convert them to an STL format. If you want deformed geometry, simply use the UPGEOM command to move your nodes to the deformed position.
The Program
Here is the source code for the windows version of the program:
/* --------------------------------------------------------------------------- PADT--------------------------------------------------- Phoenix Analysis & Design Technologies --------------------------------------------------------------------------- www.padtinc.com --------------------------------------------------------------------------- Package: ans2stl File: ans2stl.c Args: rootname Author: Eric Miller, PADT (480) 813-4884 eric.miller@padtinc.com Simple program that takes the nodes and elements from the surface of an ANSYS FE model and converts it to a binary STL file. USAGE: Create and ANSYS surface mesh one of two ways: 1: amesh the surface with triangles 2: esurf an existing mesh with triangles Write the triangle surface mesh out with nwrite/ewrite Run ans2stl with the rootname of the *.node and *.elem files as the only argument This should create a binary STL file ASSUMPTIONS: The ANSYS elements are 4 noded shells (MESH200 is suggested) in triangular format (nodes 3 and 4 the same) This code has been succesfully compiled and tested on WindowsNT NOTE: There is a known issue on UNIX with byte order Please contact me if you need a UNIX version COMPILE: gcc -o ans2stl_win ans2stl_win.c 10/31/01: Cleaned up for release to XANSYS and such 1/13/2014: Yikes, its been 12+ years. A little update and publish on The Focus blog Checked it to see if it works with Windows 7. It still compiles with GCC just fine. --------------------------------------------------------------------------- PADT, Inc. provides this software to the general public as a curtesy. Neither the company or its employees are responsible for the use or accuracy of this software. In short, it is free, and you get what you pay for. --------------------------------------------------------------------------- */ /*====================================================== SAMPLE ANSYS INPUT DECK THAT SHOWS USAGE finish /clear /file,a2stest /PREP7 !---------- ! Build silly geometry BLC4,-0.6,0.35,1,-0.75,0.55 SPH4,-0.8,-0.4,0.45 CON4,-0.15,-0.55,0.05,0.35,0.55 VADD,all !------------------------ ! Mesh surface with non-solved (MESH200) triangles et,1,200,4 MSHAPE,1,2D ! Use triangles for Areas MSHKEY,0 ! Free mesh SMRTSIZE,,,,,5 AMESH,all !---------------------- ! Write out nodes and elements nwrite,a2stest,node ewrite,a2stest,elem !-------------------- ! Execute the ans2stl program /sys,ans2stl_win.exe a2stest ======================================================= */ #include #include #include typedef struct vertStruct *vert; typedef struct facetStruct *facets; typedef struct facetListStruct *facetList; int ie[8][999999]; float coord[3][999999]; int np[999999]; struct vertStruct { float x,y,z; float nx,ny,nz; int ivrt; facetList firstFacet; }; struct facetListStruct { facets facet; facetList next; }; struct facetStruct { float xn,yn,zn; vert v1,v2,v3; }; facets theFacets; vert theVerts; char stlInpFile[80]; float xmin,xmax,ymin,ymax,zmin,zmax; float ftrAngle; int nf,nv; void swapit(); void readBin(); void getnorm(); long readnodes(); long readelems(); /*--------------------------------*/ main(argc,argv) int argc; char *argv[]; { char nfname[255]; char efname[255]; char sfname[255]; char s4[4]; FILE *sfile; int nnode,nelem,i,i1,i2,i3; float xn,yn,zn; if(argc <= 1){ puts("Usage: ans2stl file_root"); exit(1); } sprintf(nfname,"%s.node",argv[1]); sprintf(efname,"%s.elem",argv[1]); sprintf(sfname,"%s.stl",argv[1]); nnode = readnodes(nfname); nelem = readelems(efname); nf = nelem; sfile = fopen(sfname,"wb"); fwrite("PADT STL File, Solid Binary",80,1,sfile); swapit(&nelem,s4); fwrite(s4,4,1,sfile); for(i=0;i<nelem;i++){ i1 = np[ie[0][i]]; i2 = np[ie[1][i]]; i3 = np[ie[2][i]]; getnorm(&xn,&yn,&zn,i1,i2,i3); swapit(&xn,s4); fwrite(s4,4,1,sfile); swapit(&yn,s4); fwrite(s4,4,1,sfile); swapit(&zn,s4); fwrite(s4,4,1,sfile); swapit(&coord[0][i1],s4); fwrite(s4,4,1,sfile); swapit(&coord[1][i1],s4); fwrite(s4,4,1,sfile); swapit(&coord[2][i1],s4); fwrite(s4,4,1,sfile); swapit(&coord[0][i2],s4); fwrite(s4,4,1,sfile); swapit(&coord[1][i2],s4); fwrite(s4,4,1,sfile); swapit(&coord[2][i2],s4); fwrite(s4,4,1,sfile); swapit(&coord[0][i3],s4); fwrite(s4,4,1,sfile); swapit(&coord[1][i3],s4); fwrite(s4,4,1,sfile); swapit(&coord[2][i3],s4); fwrite(s4,4,1,sfile); fwrite(s4,2,1,sfile); } fclose(sfile); puts(" "); printf(" STL Data Written to %s.stl \n",argv[1]); puts(" Done!!!!!!!!!"); exit(0); } void getnorm(xn,yn,zn,i1,i2,i3) float *xn,*yn,*zn; int i1,i2,i3; { float v1[3],v2[3]; int i; for(i=0;i<3;i++){ v1[i] = coord[i][i3] - coord[i][i2]; v2[i] = coord[i][i1] - coord[i][i2]; } *xn = (v1[1]*v2[2]) - (v1[2]*v2[1]); *yn = (v1[2]*v2[0]) - (v1[0]*v2[2]); *zn = (v1[0]*v2[1]) - (v1[1]*v2[0]); } long readelems(fname) char *fname; { long num,i; FILE *nfile; char string[256],s1[7]; num = 0; nfile = fopen(fname,"r"); if(!nfile){ puts(" error on element file open, bye!"); exit(1); } while(fgets(string,86,nfile)){ for(i=0;i<8;i++){ strncpy(s1,&string[6*i],6); s1[6] = '\0'; sscanf(s1,"%d",&ie[i][num]); } num++; } printf("Number of element read: %d\n",num); return(num); } long readnodes(fname) char *fname; { FILE *nfile; long num,typeflag,nval,ifoo; char string[256]; num = 0; nfile = fopen(fname,"r"); if(!nfile){ puts(" error on node file open, bye!"); exit(1); } while(fgets(string,100,nfile)){ sscanf(string,"%d ",&nval); switch(nval){ case(-888): typeflag = 1; break; case(-999): typeflag = 0; break; default: np[nval] = num; if(typeflag){ sscanf(string,"%d %g %g %g", &ifoo,&coord[0][num],&coord[1][num],&coord[2][num]); }else{ sscanf(string,"%d %g %g %g", &ifoo,&coord[0][num],&coord[1][num],&coord[2][num]); fgets(string,81,nfile); } num++; break; } } printf("Number of nodes read %d\n",num); return(num); } /* A Little ditty to swap the byte order, STL files are for DOS */ void swapit(s1,s2) char s1[4],s2[4]; { s2[0] = s1[0]; s2[1] = s1[1]; s2[2] = s1[2]; s2[3] = s1[3]; }
ans2stl_win_2014_01_28.zip
Creating the Nodes and Elements
I’ve created a little example macro that can be used to make an STL of deformed geometry. If you do not want the deformed geometry, simply remove or comment out the UPGEOM command. This macro is good for MAPDL or ANSYS Mechanical, just comment out the last line to use it with MAPDL:
et,999,200,4
type,999
esurf,all
finish ! exit whatever preprocessor your in
! move the RST file to a temp file for the UPCOORD. Comment out if you want
! the original geometry
/copy,file,rst,,stl_temp,rst
/prep7 ! Go in to PREP7
et,999,200,4 ! Create a dummy triangle element type, non-solved (200)
type,999 ! Make it the active type
esurf,all ! Surface mesh your model
!
! Update the geometry to the deformed shape
! The first argument is the scale factor, adjust to the appropriate level
! Comment this line out if you don’t want deformed geometry
upgeom,1000,,,stl_temp,rst
!
esel,type,999 ! Select those new elements
nelem ! Select the nodes associated with them
nwrite,stl_temp,node ! write the node file
ewrite,stl_temp,elem ! Write the element file
! Run the program to convert
! This assumes your executable in in c:\temp. If not, change to the proper
! location
/sys,c:\temp\ans2stl_win.exe stl_temp
! If this is a ANSYS Mechanical code snippet, then copy the resulting STL file up to
! the root directory for the project
! For MAPDL, Comment this line out.
/copy,stl_temp,stl,,stl_temp,stl,..\..
An Example
To prove this out using modern computing technology (remember, last time I used this was in 2001) I brought up my trusty valve body model and slammed 5000 lbs on one end, holding it on the top flange. I then inserted the Commands object into the post processing branch:
When the model is solved, that command object will get executed after ANSYS is done doing all of its post processing, creating an STL of the deformed geometry. Here is what it looks like in the output file. You can see what it looks like when APDL executes the various commands:
/COPY FILE FROM FILE= file.rst
TO FILE= stl_temp.rst
FILE file.rst COPIED TO stl_temp.rst
1
***** ANSYS – ENGINEERING ANALYSIS SYSTEM RELEASE 15.0 *****
ANSYS Multiphysics
65420042 VERSION=WINDOWS x64 08:39:44 JAN 14, 2014 CP= 22.074
valve_stl–Static Structural (A5)
Note – This ANSYS version was linked by Licensee
***** ANSYS ANALYSIS DEFINITION (PREP7) *****
ELEMENT TYPE 999 IS MESH200 3-NODE TRIA MESHING FACET
KEYOPT( 1- 6)= 4 0 0 0 0 0
KEYOPT( 7-12)= 0 0 0 0 0 0
KEYOPT(13-18)= 0 0 0 0 0 0
CURRENT NODAL DOF SET IS UX UY UZ
THREE-DIMENSIONAL MODEL
ELEMENT TYPE SET TO 999
GENERATE ELEMENTS ON SURFACE DEFINED BY SELECTED NODES
TYPE= 999 REAL= 1 MATERIAL= 1 ESYS= 0
NUMBER OF ELEMENTS GENERATED= 13648
USING FILE stl_temp.rst
THE SCALE FACTOR HAS BEEN SET TO 1000.0
USING FILE stl_temp.rst
ESEL FOR LABEL= TYPE FROM 999 TO 999 BY 1
13648 ELEMENTS (OF 43707 DEFINED) SELECTED BY ESEL COMMAND.
SELECT ALL NODES HAVING ANY ELEMENT IN ELEMENT SET.
6814 NODES (OF 53895 DEFINED) SELECTED FROM
13648 SELECTED ELEMENTS BY NELE COMMAND.
WRITE ALL SELECTED NODES TO THE NODES FILE.
START WRITING AT THE BEGINNING OF FILE stl_temp.node
6814 NODES WERE WRITTEN TO FILE= stl_temp.node
WRITE ALL SELECTED ELEMENTS TO THE ELEMENT FILE.
START WRITTING AT THE BEGINNING OF FILE stl_temp.elem
Using Format = 14(I6)
13648 ELEMENTS WERE WRITTEN TO FILE= stl_temp.elem
SYSTEM=
c:\temp\ans2stl_win.exe stl_temp
Number of nodes read 6814
Number of element read: 13648
STL Data Written to stl_temp.stl
Done!!!!!!!!!
/COPY FILE FROM FILE= stl_temp.stl
TO FILE= ..\..\stl_temp.stl
FILE stl_temp.stl COPIED TO ..\..\stl_temp.stl
The resulting STL file looks great:
I use MeshLab to view my STL files because… well it is free. Do note that the mesh looks coarser. This is because the ANSYS mesh uses TETS with midside nodes. When those faces get converted to triangles those midside nodes are removed, so you do get a coarser looking model.
And after getting bumped from the queue a couple of times by “paying” jobs, our RP group printed up a nice FDM version for me on one of our Stratasys uPrint Plus machines:
It’s kind of hard to see, so I went out to the parking lot and recorded a short video of the part, twisting it around a bit:
Here is the ANSYS Mechanical project archive if you want to play with it yourself.
Other Things to Consider
Using FE Modeler
You can use FE Modeler in a couple of different ways with STL files. First off, you can read an STL file made using the method above. If you don’t have an STL preview tool, it is an easy way to check your distorted mesh. Just chose STL as the input file format:
You get this:
If you look back up at the open dialog you will notice that it reads a bunch of mesh formats. So one thing you could do instead of using my little program, is use FE Modeler to make your STL. Instead of executing the program with a /SYS command, simply use a CDWRITE,DB command and then read the resulting *.CDB file into FE Modeler. To write out the STL, just set the “Target System” to STL and then click “Write Solver File”
You may know, or may have noticed in the image above, that FE Modeler can read other FEA meshes. So if you are using some other FEA package, which you should not, then you can make an STL file in FE Modeler as well.
Color Contours
The next obvious question is how do I get my color contours on the plot. Right now we don’t have that type of printer here at PADT, but I believe that the dominant 3D Color printer out, the former Z-Corp and now 3D Systems machines, will read ANSYS results files. Stratasys JUST announced a new color 3D Printer that makes usable parts. Right now they don’t have a way to do contours, but as soon as they do we will publish something.
Another option is to use a /SHOW,vrml option and then convert that to STL with the color information.
Scaling
Scaling is something you should think about. Not only the scaling on your deformed geometry, but the scaling on your model for printing. Units can be tricky with STL files so make sure you check your model size before you print.
Smoother STL Surfaces
Your FEA mesh may be kind of coarse and the resulting STL file is even coarser because of the whole midside node thing. Most of the smoothing tools out there will also get rid of sharp edges, so you don’t want those. Your best best is to refine your mesh or using a tool like Geomagic.
Making a CAD Model from my Deformed Mesh
Perhaps you stumbled on this posting not wanting to print your model. Maybe you want a CAD model of your deformed geometry. You would use the same process, and then use Geomagic Studio. It actually works very well and give you a usable CAD model when you are done.