1
/* ADMesh -- process triangulated solid meshes
2
* Copyright (C) 1995, 1996 Anthony D. Martin
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2, or (at your option)
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
* Questions, comments, suggestions, etc to <amartin@engr.csulb.edu>
28
#if !defined(SEEK_SET)
35
stl_open(stl_file *stl, char *file)
38
stl_count_facets(stl, file);
46
stl_initialize(stl_file *stl)
48
stl->stats.degenerate_facets = 0;
49
stl->stats.edges_fixed = 0;
50
stl->stats.facets_added = 0;
51
stl->stats.facets_removed = 0;
52
stl->stats.facets_reversed = 0;
53
stl->stats.normals_fixed = 0;
54
stl->stats.number_of_parts = 0;
55
stl->stats.original_num_facets = 0;
56
stl->stats.number_of_facets = 0;
57
stl->stats.facets_malloced = 0;
58
stl->stats.volume = -1.0;
60
stl->neighbors_start = NULL;
61
stl->facet_start = NULL;
62
stl->v_indices = NULL;
67
stl_count_facets(stl_file *stl, char *file)
70
int header_num_facets;
73
unsigned char chtest[128];
78
stl->fp = fopen(file, "r");
82
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
83
sprintf(error_msg, "stl_initialize: Couldn't open %s for reading",
89
/* Find size of file */
90
fseek(stl->fp, 0, SEEK_END);
91
file_size = ftell(stl->fp);
93
/* Check for binary or ASCII file */
94
fseek(stl->fp, HEADER_SIZE, SEEK_SET);
95
fread(chtest, sizeof(chtest), 1, stl->fp);
96
stl->stats.type = ascii;
97
for(i = 0; i < sizeof(chtest); i++)
101
stl->stats.type = binary;
102
// close and reopen with binary flag (needed on Windows)
104
stl->fp = fopen(file, "rb");
110
/* Get the header and the number of facets in the .STL file */
111
/* If the .STL file is binary, then do the following */
112
if(stl->stats.type == binary)
114
/* Test if the STL file has the right size */
115
if(((file_size - HEADER_SIZE) % SIZEOF_STL_FACET != 0)
116
|| (file_size < STL_MIN_FILE_SIZE))
118
fprintf(stderr, "The file %s has the wrong size.\n", file);
121
num_facets = (file_size - HEADER_SIZE) / SIZEOF_STL_FACET;
123
/* Read the header */
124
fread(stl->stats.header, LABEL_SIZE, 1, stl->fp);
125
stl->stats.header[80] = '\0';
127
/* Read the int following the header. This should contain # of facets */
128
fread(&header_num_facets, sizeof(int), 1, stl->fp);
129
if(num_facets != header_num_facets)
132
"Warning: File size doesn't match number of facets in the header\n");
135
/* Otherwise, if the .STL file is ASCII, then do the following */
138
/* Find the number of facets */
140
for(i = 0; i < file_size ; i++)
143
if(getc(stl->fp) == '\n')
145
if(j > 4) /* don't count short lines */
156
(i < 80) && (stl->stats.header[i] = getc(stl->fp)) != '\n'; i++);
157
stl->stats.header[i] = '\0'; /* Lose the '\n' */
158
stl->stats.header[80] = '\0';
160
num_facets = num_lines / ASCII_LINES_PER_FACET;
162
stl->stats.number_of_facets += num_facets;
163
stl->stats.original_num_facets = stl->stats.number_of_facets;
167
stl_allocate(stl_file *stl)
169
/* Allocate memory for the entire .STL file */
170
stl->facet_start = (stl_facet*)calloc(stl->stats.number_of_facets,
172
if(stl->facet_start == NULL) perror("stl_initialize");
173
stl->stats.facets_malloced = stl->stats.number_of_facets;
175
/* Allocate memory for the neighbors list */
176
stl->neighbors_start = (stl_neighbors*)
177
calloc(stl->stats.number_of_facets, sizeof(stl_neighbors));
178
if(stl->facet_start == NULL) perror("stl_initialize");
182
stl_open_merge(stl_file *stl, char *file)
186
first_facet = stl->stats.number_of_facets;
188
stl_count_facets(stl, file);
190
stl_read(stl, first_facet, 0);
194
stl_reallocate(stl_file *stl)
196
/* Reallocate more memory for the .STL file(s) */
197
stl->facet_start = (stl_facet*)realloc(stl->facet_start, stl->stats.number_of_facets *
199
if(stl->facet_start == NULL) perror("stl_initialize");
200
stl->stats.facets_malloced = stl->stats.number_of_facets;
202
/* Reallocate more memory for the neighbors list */
203
stl->neighbors_start = (stl_neighbors*)
204
realloc(stl->neighbors_start, stl->stats.number_of_facets *
205
sizeof(stl_neighbors));
206
if(stl->facet_start == NULL) perror("stl_initialize");
210
stl_read(stl_file *stl, int first_facet, int first)
215
if(stl->stats.type == binary)
217
fseek(stl->fp, HEADER_SIZE, SEEK_SET);
222
/* Skip the first line of the file */
223
while(getc(stl->fp) != '\n');
226
for(i = first_facet; i < stl->stats.number_of_facets; i++)
228
if(stl->stats.type == binary)
229
/* Read a single facet from a binary .STL file */
231
// we assume little-endian architecture!
232
fread(&facet.normal, sizeof(stl_normal), 1, stl->fp);
233
fread(&facet.vertex, sizeof(stl_vertex), 3, stl->fp);
234
fread(&facet.extra, sizeof(char), 2, stl->fp);
237
/* Read a single facet from an ASCII .STL file */
239
fscanf(stl->fp, "%*s %*s %f %f %f\n", &facet.normal.x,
240
&facet.normal.y, &facet.normal.z);
241
fscanf(stl->fp, "%*s %*s");
242
fscanf(stl->fp, "%*s %f %f %f\n", &facet.vertex[0].x,
243
&facet.vertex[0].y, &facet.vertex[0].z);
244
fscanf(stl->fp, "%*s %f %f %f\n", &facet.vertex[1].x,
245
&facet.vertex[1].y, &facet.vertex[1].z);
246
fscanf(stl->fp, "%*s %f %f %f\n", &facet.vertex[2].x,
247
&facet.vertex[2].y, &facet.vertex[2].z);
248
fscanf(stl->fp, "%*s");
249
fscanf(stl->fp, "%*s");
251
/* Write the facet into memory. */
252
stl->facet_start[i] = facet;
254
stl_facet_stats(stl, facet, first);
257
stl->stats.size.x = stl->stats.max.x - stl->stats.min.x;
258
stl->stats.size.y = stl->stats.max.y - stl->stats.min.y;
259
stl->stats.size.z = stl->stats.max.z - stl->stats.min.z;
260
stl->stats.bounding_diameter = sqrt(
261
stl->stats.size.x * stl->stats.size.x +
262
stl->stats.size.y * stl->stats.size.y +
263
stl->stats.size.z * stl->stats.size.z
268
stl_facet_stats(stl_file *stl, stl_facet facet, int first)
274
/* while we are going through all of the facets, let's find the */
275
/* maximum and minimum values for x, y, and z */
277
/* Initialize the max and min values the first time through*/
279
stl->stats.max.x = facet.vertex[0].x;
280
stl->stats.min.x = facet.vertex[0].x;
281
stl->stats.max.y = facet.vertex[0].y;
282
stl->stats.min.y = facet.vertex[0].y;
283
stl->stats.max.z = facet.vertex[0].z;
284
stl->stats.min.z = facet.vertex[0].z;
286
diff_x = ABS(facet.vertex[0].x - facet.vertex[1].x);
287
diff_y = ABS(facet.vertex[0].y - facet.vertex[1].y);
288
diff_z = ABS(facet.vertex[0].z - facet.vertex[1].z);
289
max_diff = STL_MAX(diff_x, diff_y);
290
max_diff = STL_MAX(diff_z, max_diff);
291
stl->stats.shortest_edge = max_diff;
296
/* now find the max and min values */
297
stl->stats.max.x = STL_MAX(stl->stats.max.x, facet.vertex[0].x);
298
stl->stats.min.x = STL_MIN(stl->stats.min.x, facet.vertex[0].x);
299
stl->stats.max.y = STL_MAX(stl->stats.max.y, facet.vertex[0].y);
300
stl->stats.min.y = STL_MIN(stl->stats.min.y, facet.vertex[0].y);
301
stl->stats.max.z = STL_MAX(stl->stats.max.z, facet.vertex[0].z);
302
stl->stats.min.z = STL_MIN(stl->stats.min.z, facet.vertex[0].z);
304
stl->stats.max.x = STL_MAX(stl->stats.max.x, facet.vertex[1].x);
305
stl->stats.min.x = STL_MIN(stl->stats.min.x, facet.vertex[1].x);
306
stl->stats.max.y = STL_MAX(stl->stats.max.y, facet.vertex[1].y);
307
stl->stats.min.y = STL_MIN(stl->stats.min.y, facet.vertex[1].y);
308
stl->stats.max.z = STL_MAX(stl->stats.max.z, facet.vertex[1].z);
309
stl->stats.min.z = STL_MIN(stl->stats.min.z, facet.vertex[1].z);
311
stl->stats.max.x = STL_MAX(stl->stats.max.x, facet.vertex[2].x);
312
stl->stats.min.x = STL_MIN(stl->stats.min.x, facet.vertex[2].x);
313
stl->stats.max.y = STL_MAX(stl->stats.max.y, facet.vertex[2].y);
314
stl->stats.min.y = STL_MIN(stl->stats.min.y, facet.vertex[2].y);
315
stl->stats.max.z = STL_MAX(stl->stats.max.z, facet.vertex[2].z);
316
stl->stats.min.z = STL_MIN(stl->stats.min.z, facet.vertex[2].z);
320
stl_close(stl_file *stl)
322
if(stl->neighbors_start != NULL)
323
free(stl->neighbors_start);
324
if(stl->facet_start != NULL)
325
free(stl->facet_start);
326
if(stl->v_indices != NULL)
327
free(stl->v_indices);
328
if(stl->v_shared != NULL)