5float float_reverse_bytes(
float x);
6int leqi(
char *string1,
char *string2);
13char *option[N_OPTIONS] = {
14 "ascii",
"binary",
"pipe"};
16char *USAGE =
"stl2sdds [<inputFile>] [<outputFile>] [-pipe[=in][,out]]\n\
17[-ascii | -binary]\n\n\
18pipe SDDS toolkit pipe option.\n\
19ascii Requests SDDS ASCII output. Default is binary.\n\
20binary Requests SDDS BINARY output.\n\
21Converts STL files to SDDS.\n\
22Program by Robert Soliday. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
24#define LINE_MAX_LEN 256
28int main(
int argc,
char **argv) {
29 char *inputFile = NULL, *outputFile = NULL;
33 long ascii = 0, stlascii = 0;
34 unsigned long pipeFlags = 0;
36 int i, n = 0, solid = 0;
39 int32_t face_num = 0, iface;
40 int32_t bigEndianMachine = 0;
41 int64_t bytes_num = 0, text_num = 0;
42 float *normalVector[3];
47 char input[LINE_MAX_LEN];
49 char token[LINE_MAX_LEN];
53 argc =
scanargs(&scanned, argc, argv);
55 fprintf(stderr,
"%s", USAGE);
59 for (iArg = 1; iArg < argc; iArg++) {
60 if (scanned[iArg].arg_type == OPTION) {
61 switch (
match_string(scanned[iArg].list[0], option, N_OPTIONS, 0)) {
69 if (!
processPipeOption(scanned[iArg].list + 1, scanned[iArg].n_items - 1, &pipeFlags)) {
70 fprintf(stderr,
"invalid -pipe syntax\n");
75 fprintf(stderr,
"stl2sdds: invalid option seen\n%s", USAGE);
84 fprintf(stderr,
"stl2sdds: too many filenames\n%s", USAGE);
94 fprintf(stderr,
"input file not found\n");
97 if (!(fd = fopen(inputFile,
"rb"))) {
98 fprintf(stderr,
"problem opening input file\n");
103 if (_setmode(_fileno(stdin), _O_BINARY) == -1) {
104 fprintf(stderr,
"error: unable to set stdin to binary mode\n");
116 bytes_num += fread(&init, 1, 6, fd);
118 if (strcasecmp(
"solid ", init) == 0) {
125 for (i = 0; i < 74; i++) {
133 bytes_num += fread(&face_num, 1,
sizeof(int32_t), fd);
134 if (bigEndianMachine) {
138 for (i = 0; i < 3; i++) {
139 normalVector[i] = malloc(
sizeof(*(normalVector[i])) * face_num);
140 vertex1[i] = malloc(
sizeof(*(vertex1[i])) * face_num);
141 vertex2[i] = malloc(
sizeof(*(vertex2[i])) * face_num);
142 vertex3[i] = malloc(
sizeof(*(vertex3[i])) * face_num);
151 for (iface = 0; iface < face_num; iface++) {
152 for (i = 0; i < 3; i++) {
153 bytes_num += fread(&(normalVector[i][iface]), 1,
sizeof(
float), fd);
154 if (bigEndianMachine) {
155 normalVector[i][iface] = float_reverse_bytes(normalVector[i][iface]);
158 for (i = 0; i < 3; i++) {
159 bytes_num += fread(&(vertex1[i][iface]), 1,
sizeof(
float), fd);
160 if (bigEndianMachine) {
161 vertex1[i][iface] = float_reverse_bytes(vertex1[i][iface]);
164 for (i = 0; i < 3; i++) {
165 bytes_num += fread(&(vertex2[i][iface]), 1,
sizeof(
float), fd);
166 if (bigEndianMachine) {
167 vertex2[i][iface] = float_reverse_bytes(vertex2[i][iface]);
170 for (i = 0; i < 3; i++) {
171 bytes_num += fread(&(vertex3[i][iface]), 1,
sizeof(
float), fd);
172 if (bigEndianMachine) {
173 vertex3[i][iface] = float_reverse_bytes(vertex3[i][iface]);
176 bytes_num += fread(&(attribute), 1,
sizeof(
short int), fd);
179 for (i = 0; i < 3; i++) {
180 normalVector[i] = NULL;
185 fseek(fd, 0, SEEK_SET);
186 while (fgets(input, LINE_MAX_LEN, fd) != NULL) {
187 text_num = text_num + 1;
188 for (next = input; *next !=
'\0' && isspace(*next); next++) {
190 if (*next ==
'\0' || *next ==
'#' || *next ==
'!' || *next ==
'$') {
193 sscanf(next,
"%s%n", token, &width);
196 if (leqi(token,
"facet") == TRUE) {
200 for (i = 0; i < 3; i++) {
201 normalVector[i] = malloc(
sizeof(*(normalVector[i])) * n);
202 vertex1[i] = malloc(
sizeof(*(vertex1[i])) * n);
203 vertex2[i] = malloc(
sizeof(*(vertex2[i])) * n);
204 vertex3[i] = malloc(
sizeof(*(vertex3[i])) * n);
208 for (i = 0; i < 3; i++) {
209 normalVector[i] = realloc(normalVector[i],
sizeof(*(normalVector[i])) * n);
210 vertex1[i] = realloc(vertex1[i],
sizeof(*(vertex1[i])) * n);
211 vertex2[i] = realloc(vertex2[i],
sizeof(*(vertex2[i])) * n);
212 vertex3[i] = realloc(vertex3[i],
sizeof(*(vertex3[i])) * n);
216 sscanf(next,
"%*s %e %e %e", &(normalVector[0][n - 1]), &(normalVector[1][n - 1]), &(normalVector[2][n - 1]));
218 fgets(input, LINE_MAX_LEN, fd);
219 fgets(input, LINE_MAX_LEN, fd);
220 text_num = text_num + 2;
222 sscanf(next,
"%*s %e %e %e", &(vertex1[0][n - 1]), &(vertex1[1][n - 1]), &(vertex1[2][n - 1]));
224 fgets(input, LINE_MAX_LEN, fd);
225 text_num = text_num + 1;
227 sscanf(next,
"%*s %e %e %e", &(vertex2[0][n - 1]), &(vertex2[1][n - 1]), &(vertex2[2][n - 1]));
229 fgets(input, LINE_MAX_LEN, fd);
230 text_num = text_num + 1;
232 sscanf(next,
"%*s %e %e %e", &(vertex3[0][n - 1]), &(vertex3[1][n - 1]), &(vertex3[2][n - 1]));
234 fgets(input, LINE_MAX_LEN, fd);
235 fgets(input, LINE_MAX_LEN, fd);
236 text_num = text_num + 2;
237 }
else if (leqi(token,
"color") == TRUE) {
238 fprintf(stderr,
"stl2sdds: color field seen in STL file ignored.\n");
239 }
else if (leqi(token,
"solid") == TRUE) {
242 fprintf(stderr,
"stl2sdds: More than solid field seen in STL file.\n");
245 }
else if (leqi(token,
"endsolid") == TRUE) {
247 fprintf(stderr,
"stl2sdds: Unrecognized first word on line. %s\n", token);
259 SDDSout.layout.data_mode.column_major = 1;
313 if (!SDDS_StartTable(&SDDSout, face_num)) {
366 if (!SDDS_WriteTable(&SDDSout)) {
377 for (i = 0; i < 3; i++) {
378 free(normalVector[i]);
387float float_reverse_bytes(
float x) {
397 y.ychar[0] = y.ychar[3];
401 y.ychar[1] = y.ychar[2];
407int leqi(
char *string1,
char *string2) {
413 nchar1 = strlen(string1);
414 nchar2 = strlen(string2);
416 if (nchar1 < nchar2) {
424 for (i = 0; i < nchar; i++) {
426 if (toupper(string1[i]) != toupper(string2[i])) {
434 if (nchar1 > nchar) {
435 for (i = nchar; i < nchar1; i++) {
436 if (string1[i] !=
' ') {
440 }
else if (nchar2 > nchar) {
441 for (i = nchar; i < nchar2; i++) {
442 if (string2[i] !=
' ') {
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
void SDDS_SwapLong(int32_t *data)
Swaps the endianness of a 32-bit integer.
int32_t SDDS_SetColumnFromFloats(SDDS_DATASET *SDDS_dataset, int32_t mode, float *data, int64_t rows,...)
Sets the values for a single data column using single-precision floating-point numbers.
int32_t SDDS_InitializeOutput(SDDS_DATASET *SDDS_dataset, int32_t data_mode, int32_t lines_per_row, const char *description, const char *contents, const char *filename)
Initializes the SDDS output dataset.
int32_t SDDS_DefineSimpleColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *unit, int32_t type)
Defines a simple data column within the SDDS dataset.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
int32_t SDDS_CopyString(char **target, const char *source)
Copies a source string to a target string with memory allocation.
int32_t SDDS_IsBigEndianMachine()
Determines whether the current machine uses big-endian byte ordering.
#define SDDS_FLOAT
Identifier for the float data type.
long fexists(const char *filename)
Checks if a file exists.
long match_string(char *string, char **option, long n_options, long mode)
Matches a given string against an array of option strings based on specified modes.
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
long processPipeOption(char **item, long items, unsigned long *flags)
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
void free_scanargs(SCANNED_ARG **scanned, int argc)