ASCII and Binary Stereo Lithography File writers. More...
#include <WriteSTL.hpp>
Public Member Functions | |
WriteSTL (Interface *impl) | |
Constructor. More... | |
virtual | ~WriteSTL () |
Destructor. More... | |
ErrorCode | write_file (const char *file_name, const bool overwrite, const FileOptions &opts, const EntityHandle *output_list, const int num_sets, const std::vector< std::string > &qa_list, const Tag *tag_list=NULL, int num_tags=0, int export_dimension=3) |
writes out a file More... | |
![]() | |
virtual | ~WriterIface () |
Static Public Member Functions | |
static WriterIface * | factory (Interface *) |
factory method forSTL writer More... | |
Protected Types | |
enum | ByteOrder { STL_BIG_ENDIAN , STL_LITTLE_ENDIAN , STL_UNKNOWN_BYTE_ORDER } |
Protected Member Functions | |
ErrorCode | ascii_write_triangles (FILE *file, const char header[81], const Range &triangles, int precision) |
Write list of triangles to an STL file. More... | |
ErrorCode | binary_write_triangles (FILE *file, const char header[81], ByteOrder byte_order, const Range &triangles) |
Write list of triangles to an STL file. More... | |
ErrorCode | get_triangle_data (const double vtx_coords[9], float v1[3], float v2[3], float v3[3], float n[3]) |
Given an array of vertex coordinates for a triangle, pass back individual point coordinates as floats and calculate triangle normal. More... | |
ErrorCode | get_triangle_data (const double vtx_coords[9], CartVect &v1, CartVect &v2, CartVect &v3, CartVect &n) |
Protected Attributes | |
Interface * | mbImpl |
interface instance More... | |
WriteUtilIface * | mWriteIface |
Private Member Functions | |
ErrorCode | make_header (char header[81], const std::vector< std::string > &qa_list) |
Construct 80-byte, null-terminated description string from qa_list. Unused space in header will be null-char padded. More... | |
ErrorCode | get_triangles (const EntityHandle *set_array, int set_array_length, Range &triangles) |
Get triangles to write from input array of entity sets. If no sets, gets all triangles. More... | |
FILE * | open_file (const char *name, bool overwrite, bool binary) |
Open a file, respecting passed overwrite value and subclass-specified value for need_binary_io(). More... | |
ASCII and Binary Stereo Lithography File writers.
This writer will write only the MBTRI elements in the mesh. It will not decompose other 2-D elements into triangles, nor will it skin the mesh or do any other high-level operation to generate triangles from 3-D elements.
Binary files will be written with a little-endian byte order by default. The byte order can be controlled with writer options.
Definition at line 42 of file WriteSTL.hpp.
|
protected |
Enumerator | |
---|---|
STL_BIG_ENDIAN | |
STL_LITTLE_ENDIAN | |
STL_UNKNOWN_BYTE_ORDER |
Definition at line 67 of file WriteSTL.hpp.
68 { 69 STL_BIG_ENDIAN, 70 STL_LITTLE_ENDIAN, 71 STL_UNKNOWN_BYTE_ORDER 72 };
WriteSTL::WriteSTL | ( | Interface * | impl | ) |
Constructor.
Definition at line 59 of file WriteSTL.cpp.
59 : mbImpl( impl ) 60 { 61 impl->query_interface( mWriteIface ); 62 }
References mWriteIface, and moab::Interface::query_interface().
Referenced by factory().
|
virtual |
Destructor.
Definition at line 64 of file WriteSTL.cpp.
65 { 66 mbImpl->release_interface( mWriteIface ); 67 }
References mbImpl, mWriteIface, and moab::Interface::release_interface().
|
protected |
Write list of triangles to an STL file.
Definition at line 234 of file WriteSTL.cpp.
235 {
236 const char solid_name[] = "MOAB";
237
238 char myheader[81] = "solid ";
239 strcat( myheader, solid_name );
240 strncat( myheader, header, 80 );
241
242 if( EOF == fputs( myheader, file ) || EOF == fputs( "\n", file ) ) return MB_FILE_WRITE_ERROR;
243
244 ErrorCode rval;
245 double coords[9];
246 CartVect v1, v2, v3, n;
247 for( Range::const_iterator iter = triangles.begin(); iter != triangles.end(); ++iter )
248 {
249 const EntityHandle* conn;
250 int num_vtx;
251
252 rval = mbImpl->get_connectivity( *iter, conn, num_vtx );
253 if( MB_SUCCESS != rval ) return rval;
254 if( num_vtx != 3 ) return MB_FAILURE;
255
256 rval = mbImpl->get_coords( conn, 3, coords );
257 if( MB_SUCCESS != rval ) return rval;
258
259 rval = get_triangle_data( coords, v1, v2, v3, n );
260 if( MB_SUCCESS != rval ) return rval;
261
262 fprintf( file, "facet normal %e %e %e\n", n[0], n[1], n[2] );
263 fprintf( file, "outer loop\n" );
264 fprintf( file, "vertex %.*e %.*e %.*e\n", prec, (float)v1[0], prec, (float)v1[1], prec, (float)v1[2] );
265 fprintf( file, "vertex %.*e %.*e %.*e\n", prec, (float)v2[0], prec, (float)v2[1], prec, (float)v2[2] );
266 fprintf( file, "vertex %.*e %.*e %.*e\n", prec, (float)v3[0], prec, (float)v3[1], prec, (float)v3[2] );
267 fprintf( file, "endloop\n" );
268 fprintf( file, "endfacet\n" );
269 }
270
271 fprintf( file, "endsolid %s\n", solid_name );
272 return MB_SUCCESS;
273 }
References moab::Range::begin(), moab::Range::end(), ErrorCode, moab::Interface::get_connectivity(), moab::Interface::get_coords(), get_triangle_data(), MB_FILE_WRITE_ERROR, MB_SUCCESS, and mbImpl.
Referenced by write_file().
|
protected |
Write list of triangles to an STL file.
Definition at line 284 of file WriteSTL.cpp.
288 {
289 ErrorCode rval;
290 if( 1 != fwrite( header, 80, 1, file ) ) return MB_FILE_WRITE_ERROR;
291
292 // Default to little endian if byte_order == UNKNOWN_BYTE_ORDER
293 const bool want_big_endian = ( byte_order == STL_BIG_ENDIAN );
294 const bool am_big_endian = !SysUtil::little_endian();
295 const bool swap_bytes = ( want_big_endian == am_big_endian );
296
297 if( triangles.size() > INT_MAX ) // Can't write that many triangles
298 return MB_FAILURE;
299
300 uint32_t count = (uint32_t)triangles.size();
301 if( swap_bytes ) SysUtil::byteswap( &count, 1 );
302 if( 1 != fwrite( &count, 4, 1, file ) ) return MB_FILE_WRITE_ERROR;
303
304 double coords[9];
305 BinTri tri;
306 tri.pad[0] = tri.pad[1] = '\0';
307 for( Range::const_iterator iter = triangles.begin(); iter != triangles.end(); ++iter )
308 {
309 const EntityHandle* conn;
310 int num_vtx;
311
312 rval = mbImpl->get_connectivity( *iter, conn, num_vtx );
313 if( MB_SUCCESS != rval ) return rval;
314 if( num_vtx != 3 ) return MB_FAILURE;
315
316 rval = mbImpl->get_coords( conn, 3, coords );
317 if( MB_SUCCESS != rval ) return rval;
318
319 rval = get_triangle_data( coords, tri.vertex1, tri.vertex2, tri.vertex3, tri.normal );
320 if( MB_SUCCESS != rval ) return rval;
321
322 if( swap_bytes )
323 {
324 SysUtil::byteswap( tri.normal, 3 );
325 SysUtil::byteswap( tri.vertex1, 3 );
326 SysUtil::byteswap( tri.vertex2, 3 );
327 SysUtil::byteswap( tri.vertex3, 3 );
328 }
329
330 if( 1 != fwrite( &tri, 50, 1, file ) ) return MB_FILE_WRITE_ERROR;
331 }
332
333 return MB_SUCCESS;
334 }
References moab::Range::begin(), moab::SysUtil::byteswap(), moab::Range::end(), ErrorCode, moab::Interface::get_connectivity(), moab::Interface::get_coords(), get_triangle_data(), moab::SysUtil::little_endian(), MB_FILE_WRITE_ERROR, MB_SUCCESS, mbImpl, moab::BinTri::normal, moab::BinTri::pad, moab::Range::size(), STL_BIG_ENDIAN, moab::SysUtil::swap_bytes(), moab::BinTri::vertex1, moab::BinTri::vertex2, and moab::BinTri::vertex3.
Referenced by write_file().
|
static |
factory method forSTL writer
Definition at line 54 of file WriteSTL.cpp.
55 {
56 return new WriteSTL( iface );
57 }
References iface, and WriteSTL().
Referenced by moab::ReaderWriterSet::ReaderWriterSet().
|
protected |
Definition at line 221 of file WriteSTL.cpp.
222 {
223 v1 = coords;
224 v2 = coords + 3;
225 v3 = coords + 6;
226
227 n = ( v2 - v1 ) * ( v3 - v1 );
228
229 n.normalize();
230
231 return MB_SUCCESS;
232 }
References MB_SUCCESS, and moab::CartVect::normalize().
|
protected |
Given an array of vertex coordinates for a triangle, pass back individual point coordinates as floats and calculate triangle normal.
Definition at line 207 of file WriteSTL.cpp.
208 {
209 CartVect cv1, cv2, cv3, cn;
210 ErrorCode rval = get_triangle_data( coords, cv1, cv2, cv3, cn );
211 if( MB_SUCCESS != rval ) return rval;
212
213 cv1.get( v1 );
214 cv2.get( v2 );
215 cv3.get( v3 );
216 cn.get( n );
217
218 return MB_SUCCESS;
219 }
References ErrorCode, moab::CartVect::get(), and MB_SUCCESS.
Referenced by ascii_write_triangles(), and binary_write_triangles().
|
private |
Get triangles to write from input array of entity sets. If no sets, gets all triangles.
Definition at line 190 of file WriteSTL.cpp.
191 {
192 if( !set_array || 0 == set_array_length ) return mbImpl->get_entities_by_type( 0, MBTRI, triangles );
193
194 const EntityHandle* iter = set_array;
195 const EntityHandle* end = iter + set_array_length;
196 for( ; iter != end; ++iter )
197 {
198 Range r;
199 ErrorCode rval = mbImpl->get_entities_by_type( *iter, MBTRI, r, true );
200 if( MB_SUCCESS != rval ) return rval;
201 triangles.merge( r );
202 }
203
204 return MB_SUCCESS;
205 }
References ErrorCode, moab::Interface::get_entities_by_type(), MB_SUCCESS, mbImpl, MBTRI, and moab::Range::merge().
Referenced by write_file().
|
private |
Construct 80-byte, null-terminated description string from qa_list. Unused space in header will be null-char padded.
Definition at line 172 of file WriteSTL.cpp.
173 {
174 memset( header, 0, 81 );
175
176 std::string result;
177 for( std::vector< std::string >::const_iterator i = qa_list.begin(); i != qa_list.end(); ++i )
178 {
179 result += " ";
180 result += *i;
181 }
182
183 size_t len = result.size();
184 if( len > 80 ) len = 80;
185 memcpy( header, result.c_str(), len );
186
187 return MB_SUCCESS;
188 }
References MB_SUCCESS.
Referenced by write_file().
|
private |
Open a file, respecting passed overwrite value and subclass-specified value for need_binary_io().
Definition at line 134 of file WriteSTL.cpp.
135 {
136 // Open file with write access, and create it if it doesn't exist.
137 int flags = O_WRONLY | O_CREAT;
138 // Select behavior if the named file already exists. If
139 // overwrite is true, truncate the file. If it is false,
140 // make the call to open() fail.
141 if( overwrite )
142 flags |= O_TRUNC;
143 else
144 flags |= O_EXCL;
145 // If platform defines a "binary" bit in the file access
146 // flags (i.e. we're building on windows), then set it
147 // if we're writing a binary file.
148 #ifdef O_BINARY
149 if( binary ) flags |= O_BINARY;
150 #endif
151
152 // Give everyone read and write, but not execute, permission.
153 // These are not the final permissions for the file. Permissions
154 // are removed according to the user's umask. All we want to
155 // say here is that the executable bits should not be set because
156 // this isn't an executable file. Everything else is a user
157 // preference and should be left up to the umask.
158 int creat_mode = _S_IREAD | _S_IWRITE;
159
160 // Open the file.
161 int fd = open( name, flags, creat_mode );
162 if( fd < 0 )
163 {
164 MB_SET_ERR_RET_VAL( name << ": " << strerror( errno ), NULL );
165 }
166 FILE* result = fdopen( fd, binary ? "wb" : "w" );
167 if( !result ) close( fd );
168
169 return result;
170 }
References _S_IREAD, _S_IWRITE, and MB_SET_ERR_RET_VAL.
Referenced by write_file().
|
virtual |
writes out a file
Implements moab::WriterIface.
Definition at line 69 of file WriteSTL.cpp.
78 {
79 char header[81];
80 Range triangles;
81 ErrorCode rval;
82
83 if( tag_list && num_tags )
84 {
85 MB_SET_ERR( MB_TYPE_OUT_OF_RANGE, "STL file does not support tag data" );
86 }
87
88 rval = make_header( header, qa_list );
89 if( MB_SUCCESS != rval ) return rval;
90
91 rval = get_triangles( ent_handles, num_sets, triangles );
92 if( MB_SUCCESS != rval ) return rval;
93
94 if( triangles.empty() )
95 {
96 MB_SET_ERR( MB_ENTITY_NOT_FOUND, "No triangles to write" );
97 }
98
99 bool is_ascii = false, is_binary = false;
100 if( MB_SUCCESS == opts.get_null_option( "ASCII" ) ) is_ascii = true;
101 if( MB_SUCCESS == opts.get_null_option( "BINARY" ) ) is_binary = true;
102 if( is_ascii && is_binary )
103 {
104 MB_SET_ERR( MB_FAILURE, "Conflicting options: BINARY ASCII" );
105 }
106
107 bool big_endian = false, little_endian = false;
108 if( MB_SUCCESS == opts.get_null_option( "BIG_ENDIAN" ) ) big_endian = true;
109 if( MB_SUCCESS == opts.get_null_option( "LITTLE_ENDIAN" ) ) little_endian = true;
110 if( big_endian && little_endian )
111 {
112 MB_SET_ERR( MB_FAILURE, "Conflicting options: BIG_ENDIAN LITTLE_ENDIAN" );
113 }
114 ByteOrder byte_order = big_endian ? STL_BIG_ENDIAN : little_endian ? STL_LITTLE_ENDIAN : STL_UNKNOWN_BYTE_ORDER;
115
116 FILE* file = open_file( file_name, overwrite, is_binary );
117 if( !file ) return MB_FILE_DOES_NOT_EXIST;
118
119 if( is_binary )
120 rval = binary_write_triangles( file, header, byte_order, triangles );
121 else
122 {
123 // Get precision for node coordinates
124 int precision;
125 if( MB_SUCCESS != opts.get_int_option( "PRECISION", precision ) ) precision = DEFAULT_PRECISION;
126
127 rval = ascii_write_triangles( file, header, triangles, precision );
128 }
129
130 fclose( file );
131 return rval;
132 }
References ascii_write_triangles(), moab::SysUtil::big_endian(), binary_write_triangles(), moab::DEFAULT_PRECISION, moab::Range::empty(), ErrorCode, moab::FileOptions::get_int_option(), moab::FileOptions::get_null_option(), get_triangles(), moab::SysUtil::little_endian(), make_header(), MB_ENTITY_NOT_FOUND, MB_FILE_DOES_NOT_EXIST, MB_SET_ERR, MB_SUCCESS, MB_TYPE_OUT_OF_RANGE, open_file(), STL_BIG_ENDIAN, STL_LITTLE_ENDIAN, and STL_UNKNOWN_BYTE_ORDER.
|
protected |
interface instance
Definition at line 87 of file WriteSTL.hpp.
Referenced by ascii_write_triangles(), binary_write_triangles(), get_triangles(), and ~WriteSTL().
|
protected |
Definition at line 88 of file WriteSTL.hpp.
Referenced by WriteSTL(), and ~WriteSTL().