~ubuntu-branches/ubuntu/utopic/slic3r/utopic

« back to all changes in this revision

Viewing changes to xs/src/admesh/stlinit.c

  • Committer: Package Import Robot
  • Author(s): Chow Loong Jin
  • Date: 2014-06-17 01:27:26 UTC
  • Revision ID: package-import@ubuntu.com-20140617012726-2wrs4zdo251nr4vg
Tags: upstream-1.1.4+dfsg
ImportĀ upstreamĀ versionĀ 1.1.4+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  ADMesh -- process triangulated solid meshes
 
2
 *  Copyright (C) 1995, 1996  Anthony D. Martin
 
3
 *
 
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)
 
7
 *  any later version.
 
8
 *
 
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.
 
13
 *
 
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.
 
17
 *  
 
18
 *  Questions, comments, suggestions, etc to <amartin@engr.csulb.edu>
 
19
 */
 
20
 
 
21
#include <stdio.h>
 
22
#include <stdlib.h>
 
23
#include <string.h>
 
24
#include <math.h>
 
25
 
 
26
#include "stl.h"
 
27
 
 
28
#if !defined(SEEK_SET)
 
29
#define SEEK_SET 0
 
30
#define SEEK_CUR 1
 
31
#define SEEK_END 2
 
32
#endif
 
33
 
 
34
void
 
35
stl_open(stl_file *stl, char *file)
 
36
{
 
37
  stl_initialize(stl);
 
38
  stl_count_facets(stl, file);
 
39
  stl_allocate(stl);
 
40
  stl_read(stl, 0, 1);
 
41
  fclose(stl->fp);
 
42
}
 
43
 
 
44
 
 
45
void
 
46
stl_initialize(stl_file *stl)
 
47
{
 
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;
 
59
  
 
60
  stl->neighbors_start = NULL;
 
61
  stl->facet_start = NULL;
 
62
  stl->v_indices = NULL;
 
63
  stl->v_shared = NULL;
 
64
}
 
65
 
 
66
static void
 
67
stl_count_facets(stl_file *stl, char *file)
 
68
{
 
69
  long           file_size;
 
70
  int            header_num_facets;
 
71
  int            num_facets;
 
72
  int            i, j;
 
73
  unsigned char  chtest[128];
 
74
  int            num_lines = 1;
 
75
  char           *error_msg;
 
76
  
 
77
  /* Open the file */
 
78
  stl->fp = fopen(file, "r");
 
79
  if(stl->fp == NULL)
 
80
    {
 
81
      error_msg = (char*)
 
82
        malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
 
83
      sprintf(error_msg, "stl_initialize: Couldn't open %s for reading",
 
84
              file);
 
85
      perror(error_msg);
 
86
      free(error_msg);
 
87
      exit(1);
 
88
    }
 
89
  /* Find size of file */
 
90
  fseek(stl->fp, 0, SEEK_END);
 
91
  file_size = ftell(stl->fp);
 
92
  
 
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++)
 
98
    {
 
99
      if(chtest[i] > 127)
 
100
        {
 
101
          stl->stats.type = binary;
 
102
          // close and reopen with binary flag (needed on Windows)
 
103
          fclose(stl->fp);
 
104
          stl->fp = fopen(file, "rb");
 
105
          break;
 
106
        }
 
107
    }
 
108
  rewind(stl->fp);
 
109
 
 
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)
 
113
    {
 
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))
 
117
        {
 
118
          fprintf(stderr, "The file %s has the wrong size.\n", file);
 
119
          exit(1);
 
120
        }
 
121
      num_facets = (file_size - HEADER_SIZE) / SIZEOF_STL_FACET;
 
122
 
 
123
      /* Read the header */
 
124
      fread(stl->stats.header, LABEL_SIZE, 1, stl->fp);
 
125
      stl->stats.header[80] = '\0';
 
126
 
 
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)
 
130
        {
 
131
          fprintf(stderr, 
 
132
          "Warning: File size doesn't match number of facets in the header\n");
 
133
        }
 
134
    }
 
135
  /* Otherwise, if the .STL file is ASCII, then do the following */
 
136
  else
 
137
    {
 
138
      /* Find the number of facets */
 
139
      j = 0;
 
140
      for(i = 0; i < file_size ; i++)
 
141
        {
 
142
          j++;
 
143
          if(getc(stl->fp) == '\n')
 
144
            {
 
145
              if(j > 4) /* don't count short lines */
 
146
                {
 
147
                  num_lines++;
 
148
                }
 
149
              j = 0;
 
150
            }
 
151
        }
 
152
      rewind(stl->fp);
 
153
 
 
154
      /* Get the header */
 
155
      for(i = 0; 
 
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';
 
159
      
 
160
      num_facets = num_lines / ASCII_LINES_PER_FACET;
 
161
    }
 
162
  stl->stats.number_of_facets += num_facets;
 
163
  stl->stats.original_num_facets = stl->stats.number_of_facets;
 
164
}
 
165
 
 
166
void
 
167
stl_allocate(stl_file *stl)
 
168
{
 
169
  /*  Allocate memory for the entire .STL file */
 
170
  stl->facet_start = (stl_facet*)calloc(stl->stats.number_of_facets, 
 
171
                            sizeof(stl_facet));
 
172
  if(stl->facet_start == NULL) perror("stl_initialize");
 
173
  stl->stats.facets_malloced = stl->stats.number_of_facets;
 
174
 
 
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");
 
179
}
 
180
 
 
181
void
 
182
stl_open_merge(stl_file *stl, char *file)
 
183
{
 
184
  int first_facet;
 
185
  
 
186
  first_facet = stl->stats.number_of_facets;
 
187
  stl_initialize(stl);
 
188
  stl_count_facets(stl, file);
 
189
  stl_reallocate(stl);
 
190
  stl_read(stl, first_facet, 0);
 
191
}
 
192
 
 
193
extern void
 
194
stl_reallocate(stl_file *stl)
 
195
{
 
196
  /*  Reallocate more memory for the .STL file(s) */
 
197
  stl->facet_start = (stl_facet*)realloc(stl->facet_start, stl->stats.number_of_facets *
 
198
                             sizeof(stl_facet));
 
199
  if(stl->facet_start == NULL) perror("stl_initialize");
 
200
  stl->stats.facets_malloced = stl->stats.number_of_facets;
 
201
 
 
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");
 
207
}
 
208
 
 
209
static void
 
210
stl_read(stl_file *stl, int first_facet, int first)
 
211
{
 
212
  stl_facet facet;
 
213
  int   i;
 
214
 
 
215
  if(stl->stats.type == binary)
 
216
    {
 
217
      fseek(stl->fp, HEADER_SIZE, SEEK_SET);
 
218
    }
 
219
  else
 
220
    {
 
221
      rewind(stl->fp);
 
222
      /* Skip the first line of the file */
 
223
      while(getc(stl->fp) != '\n');
 
224
    }
 
225
 
 
226
  for(i = first_facet; i < stl->stats.number_of_facets; i++)
 
227
    {
 
228
      if(stl->stats.type == binary)
 
229
        /* Read a single facet from a binary .STL file */
 
230
        {
 
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);
 
235
        }
 
236
      else
 
237
        /* Read a single facet from an ASCII .STL file */
 
238
        {
 
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");
 
250
        }
 
251
      /* Write the facet into memory. */
 
252
      stl->facet_start[i] = facet;
 
253
      
 
254
      stl_facet_stats(stl, facet, first);
 
255
      first = 0;
 
256
    }
 
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
 
264
        );
 
265
}
 
266
 
 
267
void
 
268
stl_facet_stats(stl_file *stl, stl_facet facet, int first)
 
269
{
 
270
    float diff_x;
 
271
    float diff_y;
 
272
    float diff_z;
 
273
    float max_diff;
 
274
    /* while we are going through all of the facets, let's find the  */
 
275
    /* maximum and minimum values for x, y, and z  */
 
276
    
 
277
    /* Initialize the max and min values the first time through*/
 
278
    if (first) {
 
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;
 
285
        
 
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;
 
292
        
 
293
        first = 0;
 
294
    }
 
295
    
 
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);
 
303
    
 
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);
 
310
    
 
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);
 
317
}
 
318
 
 
319
void
 
320
stl_close(stl_file *stl)
 
321
{
 
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)
 
329
        free(stl->v_shared);
 
330
}
 
331