SDDSlib
Loading...
Searching...
No Matches
sdds2stl.c File Reference

Converts SDDS (Self-Describing Data Set) files into binary STL (stereolithography) files. More...

#include "mdb.h"
#include "SDDS.h"
#include "scan.h"

Go to the source code of this file.

Enumerations

enum  option_type { SET_PIPE , N_OPTIONS }
 

Functions

float float_reverse_bytes (float x)
 
int main (int argc, char **argv)
 

Variables

char * option [N_OPTIONS]
 
char * usage
 

Detailed Description

Converts SDDS (Self-Describing Data Set) files into binary STL (stereolithography) files.

This program reads an SDDS file, extracts normal vectors and vertex coordinates, and writes them into a binary STL file. It supports optional piped input/output and adheres to SDDS conventions for data processing.

Features:

  • Handles various SDDS data types.
  • Provides big-endian and little-endian support for portability.
  • Can process data directly from stdin or output to stdout using pipe options.

Usage:

sdds2stl [-pipe[=input]] [<inputFile>] [<outputFile>]
Note
Ensure the input SDDS file contains the required columns:
  • NormalVectorX, NormalVectorY, NormalVectorZ
  • Vertex1X, Vertex1Y, Vertex1Z
  • Vertex2X, Vertex2Y, Vertex2Z
  • Vertex3X, Vertex3Y, Vertex3Z
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
R. Soliday

Definition in file sdds2stl.c.

Enumeration Type Documentation

◆ option_type

enum option_type

Definition at line 47 of file sdds2stl.c.

47 {
48 SET_PIPE,
49 N_OPTIONS
50};

Function Documentation

◆ float_reverse_bytes()

float float_reverse_bytes ( float x)

Definition at line 269 of file sdds2stl.c.

269 {
270 char c;
271 union {
272 float yfloat;
273 char ychar[4];
274 } y;
275
276 y.yfloat = x;
277
278 c = y.ychar[0];
279 y.ychar[0] = y.ychar[3];
280 y.ychar[3] = c;
281
282 c = y.ychar[1];
283 y.ychar[1] = y.ychar[2];
284 y.ychar[2] = c;
285
286 return y.yfloat;
287}

◆ main()

int main ( int argc,
char ** argv )

Definition at line 61 of file sdds2stl.c.

61 {
62 char *input = NULL, *output = NULL;
63 SDDS_DATASET SDDS_dataset;
64 SCANNED_ARG *scanned;
65 long i_arg;
66 unsigned long pipe_flags = 0;
67
68 int i;
69 int64_t rows = 0;
70 int32_t row, bsrows;
71 float *normal_vector[3];
72 float *vertex1[3];
73 float *vertex2[3];
74 float *vertex3[3];
75 short attribute = 0;
76 FILE *fd;
77 int32_t big_endian_machine = 0;
78 float temp;
79
81 argc = scanargs(&scanned, argc, argv);
82 if (argc < 2) {
83 fprintf(stderr, "%s", usage);
84 return 1;
85 }
86
87 for (i_arg = 1; i_arg < argc; i_arg++) {
88 if (scanned[i_arg].arg_type == OPTION) {
89 switch (match_string(scanned[i_arg].list[0], option, N_OPTIONS, 0)) {
90 case SET_PIPE:
91 if (!processPipeOption(scanned[i_arg].list + 1, scanned[i_arg].n_items - 1, &pipe_flags)) {
92 fprintf(stderr, "sdds2stl: invalid -pipe syntax\n");
93 return 1;
94 }
95 break;
96 default:
97 fprintf(stderr, "sdds2stl: invalid option seen\n%s", usage);
98 return 1;
99 }
100 } else {
101 if (!input)
102 SDDS_CopyString(&input, scanned[i_arg].list[0]);
103 else if (!output)
104 SDDS_CopyString(&output, scanned[i_arg].list[0]);
105 else {
106 fprintf(stderr, "sdds2stl: too many filenames\n%s", usage);
107 return 1;
108 }
109 }
110 }
111
112 if (pipe_flags & USE_STDIN)
113 processFilenames("sdds2tiff", &input, &output, USE_STDIN, 1, NULL);
114
115 if (!SDDS_InitializeInput(&SDDS_dataset, input))
116 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
117
118 if ((SDDS_CheckColumn(&SDDS_dataset, "NormalVectorX", NULL, SDDS_ANY_NUMERIC_TYPE, NULL)) != SDDS_CHECK_OKAY) {
119 fprintf(stderr, "sdds2stl: NormalVectorX column not found.\n");
120 return 1;
121 }
122
123 if ((SDDS_CheckColumn(&SDDS_dataset, "NormalVectorY", NULL, SDDS_ANY_NUMERIC_TYPE, NULL)) != SDDS_CHECK_OKAY) {
124 fprintf(stderr, "sdds2stl: NormalVectorX column not found.\n");
125 return 1;
126 }
127
128 if ((SDDS_CheckColumn(&SDDS_dataset, "NormalVectorZ", NULL, SDDS_ANY_NUMERIC_TYPE, NULL)) != SDDS_CHECK_OKAY) {
129 fprintf(stderr, "sdds2stl: NormalVectorX column not found.\n");
130 return 1;
131 }
132
133 if ((SDDS_CheckColumn(&SDDS_dataset, "Vertex1X", NULL, SDDS_ANY_NUMERIC_TYPE, NULL)) != SDDS_CHECK_OKAY) {
134 fprintf(stderr, "sdds2stl: Vertex1X column not found.\n");
135 return 1;
136 }
137
138 if ((SDDS_CheckColumn(&SDDS_dataset, "Vertex1Y", NULL, SDDS_ANY_NUMERIC_TYPE, NULL)) != SDDS_CHECK_OKAY) {
139 fprintf(stderr, "sdds2stl: Vertex1Y column not found.\n");
140 return 1;
141 }
142
143 if ((SDDS_CheckColumn(&SDDS_dataset, "Vertex1Z", NULL, SDDS_ANY_NUMERIC_TYPE, NULL)) != SDDS_CHECK_OKAY) {
144 fprintf(stderr, "sdds2stl: Vertex1Z column not found.\n");
145 return 1;
146 }
147
148 if ((SDDS_CheckColumn(&SDDS_dataset, "Vertex2X", NULL, SDDS_ANY_NUMERIC_TYPE, NULL)) != SDDS_CHECK_OKAY) {
149 fprintf(stderr, "sdds2stl: Vertex2X column not found.\n");
150 return 1;
151 }
152
153 if ((SDDS_CheckColumn(&SDDS_dataset, "Vertex2Y", NULL, SDDS_ANY_NUMERIC_TYPE, NULL)) != SDDS_CHECK_OKAY) {
154 fprintf(stderr, "sdds2stl: Vertex2Y column not found.\n");
155 return 1;
156 }
157
158 if ((SDDS_CheckColumn(&SDDS_dataset, "Vertex2Z", NULL, SDDS_ANY_NUMERIC_TYPE, NULL)) != SDDS_CHECK_OKAY) {
159 fprintf(stderr, "sdds2stl: Vertex2Z column not found.\n");
160 return 1;
161 }
162
163 if ((SDDS_CheckColumn(&SDDS_dataset, "Vertex3X", NULL, SDDS_ANY_NUMERIC_TYPE, NULL)) != SDDS_CHECK_OKAY) {
164 fprintf(stderr, "sdds2stl: Vertex3X column not found.\n");
165 return 1;
166 }
167
168 if ((SDDS_CheckColumn(&SDDS_dataset, "Vertex3Y", NULL, SDDS_ANY_NUMERIC_TYPE, NULL)) != SDDS_CHECK_OKAY) {
169 fprintf(stderr, "sdds2stl: Vertex3Y column not found.\n");
170 return 1;
171 }
172
173 if ((SDDS_CheckColumn(&SDDS_dataset, "Vertex3Z", NULL, SDDS_ANY_NUMERIC_TYPE, NULL)) != SDDS_CHECK_OKAY) {
174 fprintf(stderr, "sdds2stl: Vertex3Z column not found.\n");
175 return 1;
176 }
177
178 if (SDDS_ReadTable(&SDDS_dataset) <= 0) {
179 fprintf(stderr, "sdds2stl: Unable to read SDDS page.\n");
180 return 1;
181 }
182
183 rows = SDDS_RowCount(&SDDS_dataset);
184 if (rows > INT32_MAX) {
185 fprintf(stderr, "sdds2stl: Too many rows input file for conversion to STL format\n");
186 return 1;
187 }
188
189 for (i = 0; i < 3; i++) {
190 normal_vector[i] = malloc(sizeof(*(normal_vector[i])) * rows);
191 vertex1[i] = malloc(sizeof(*(vertex1[i])) * rows);
192 vertex2[i] = malloc(sizeof(*(vertex2[i])) * rows);
193 vertex3[i] = malloc(sizeof(*(vertex3[i])) * rows);
194 }
195
196 normal_vector[0] = SDDS_GetColumnInFloats(&SDDS_dataset, "NormalVectorX");
197 normal_vector[1] = SDDS_GetColumnInFloats(&SDDS_dataset, "NormalVectorY");
198 normal_vector[2] = SDDS_GetColumnInFloats(&SDDS_dataset, "NormalVectorZ");
199 vertex1[0] = SDDS_GetColumnInFloats(&SDDS_dataset, "Vertex1X");
200 vertex1[1] = SDDS_GetColumnInFloats(&SDDS_dataset, "Vertex1Y");
201 vertex1[2] = SDDS_GetColumnInFloats(&SDDS_dataset, "Vertex1Z");
202 vertex2[0] = SDDS_GetColumnInFloats(&SDDS_dataset, "Vertex2X");
203 vertex2[1] = SDDS_GetColumnInFloats(&SDDS_dataset, "Vertex2Y");
204 vertex2[2] = SDDS_GetColumnInFloats(&SDDS_dataset, "Vertex2Z");
205 vertex3[0] = SDDS_GetColumnInFloats(&SDDS_dataset, "Vertex3X");
206 vertex3[1] = SDDS_GetColumnInFloats(&SDDS_dataset, "Vertex3Y");
207 vertex3[2] = SDDS_GetColumnInFloats(&SDDS_dataset, "Vertex3Z");
208
209 if (!SDDS_Terminate(&SDDS_dataset))
210 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
211
212 if (!output) {
213#if defined(_WIN32)
214 if (_setmode(_fileno(stdout), _O_BINARY) == -1) {
215 fprintf(stderr, "error: unable to set stdout to binary mode\n");
216 exit(1);
217 }
218#endif
219 fd = stdout;
220 } else
221 fd = fopen(output, "wb");
222
223 big_endian_machine = SDDS_IsBigEndianMachine();
224
225 fprintf(fd, "STL BINARY FILE CREATED BY SDDS2STL --------------------------------------------");
226 if (big_endian_machine) {
227 bsrows = rows;
228 SDDS_SwapLong((int32_t *)&bsrows);
229 fwrite(&bsrows, sizeof(int32_t), 1, fd);
230 for (row = 0; row < rows; row++) {
231 for (i = 0; i < 3; i++) {
232 temp = float_reverse_bytes(normal_vector[i][row]);
233 fwrite(&temp, sizeof(float), 1, fd);
234 }
235 for (i = 0; i < 3; i++) {
236 temp = float_reverse_bytes(vertex1[i][row]);
237 fwrite(&temp, sizeof(float), 1, fd);
238 }
239 for (i = 0; i < 3; i++) {
240 temp = float_reverse_bytes(vertex2[i][row]);
241 fwrite(&temp, sizeof(float), 1, fd);
242 }
243 for (i = 0; i < 3; i++) {
244 temp = float_reverse_bytes(vertex3[i][row]);
245 fwrite(&temp, sizeof(float), 1, fd);
246 }
247 fwrite(&attribute, sizeof(short), 1, fd);
248 }
249 } else {
250 fwrite(&rows, sizeof(int32_t), 1, fd);
251 for (row = 0; row < rows; row++) {
252 for (i = 0; i < 3; i++)
253 fwrite(&(normal_vector[i][row]), sizeof(float), 1, fd);
254 for (i = 0; i < 3; i++)
255 fwrite(&(vertex1[i][row]), sizeof(float), 1, fd);
256 for (i = 0; i < 3; i++)
257 fwrite(&(vertex2[i][row]), sizeof(float), 1, fd);
258 for (i = 0; i < 3; i++)
259 fwrite(&(vertex3[i][row]), sizeof(float), 1, fd);
260 fwrite(&attribute, sizeof(short), 1, fd);
261 }
262 }
263
264 fclose(fd);
265
266 return 1;
267}
void SDDS_SwapLong(int32_t *data)
Swaps the endianness of a 32-bit integer.
float * SDDS_GetColumnInFloats(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves the data of a specified numerical column as an array of floats, considering only rows marke...
int32_t SDDS_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:49
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_CheckColumn(SDDS_DATASET *SDDS_dataset, char *name, char *units, int32_t type, FILE *fp_message)
Checks if a column exists in the SDDS dataset with the specified name, units, and type.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:432
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
int32_t SDDS_CopyString(char **target, const char *source)
Copies a source string to a target string with memory allocation.
Definition SDDS_utils.c:856
int32_t SDDS_IsBigEndianMachine()
Determines whether the current machine uses big-endian byte ordering.
#define SDDS_ANY_NUMERIC_TYPE
Special identifier used by SDDS_Check*() routines to accept any numeric type.
Definition SDDStypes.h:157
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)
Definition scanargs.c:36
long processPipeOption(char **item, long items, unsigned long *flags)
Definition scanargs.c:356
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
Definition scanargs.c:390

Variable Documentation

◆ option

char* option[N_OPTIONS]
Initial value:
=
{
"pipe"}

Definition at line 52 of file sdds2stl.c.

53 {
54 "pipe"};

◆ usage

char* usage
Initial value:
=
"sdds2stl [-pipe[=input]] [<inputFile>] [<outputFile>]\n"
"Converts an SDDS file to a binary STL file.\n"
"Program by Robert Soliday. (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n"

Definition at line 56 of file sdds2stl.c.