-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrockconvert.c
249 lines (217 loc) · 8.09 KB
/
rockconvert.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
/*************************************************************
*
* rockconvert.c - Perform a file format conversion
* of an irregular triangle mesh
*
* Mark J. Stock, [email protected]
*
*
* rocktools - Tools for creating and manipulating triangular meshes
* Copyright (C) 1999,2003-4,2006-7,14-5 Mark J. Stock
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*********************************************************** */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include "structs.h"
node_ptr node_head = NULL;
norm_ptr norm_head = NULL;
text_ptr text_head = NULL;
int num_tri = 0;
void rescale_nodes (VEC);
void translate_nodes (VEC);
void remap_to_cylinder ();
int Usage(char[MAX_FN_LEN],int);
int main(int argc,char **argv) {
int i;
char infile[MAX_FN_LEN]; /* name of input file */
char progname[MAX_FN_LEN]; /* name of binary executable */
char output_format[4]; /* file format extension for output */
tri_pointer tri_head = NULL;
int keep_normals = TRUE;
int do_rescale = FALSE;
int do_trans = FALSE;
int do_trans_first = FALSE;
int do_cyl = FALSE;
VEC scale = {1., 1., 1.};
VEC trans = {0., 0., 0.};
/* Parse command-line args */
(void) strcpy(progname,argv[0]);
if (argc < 2) (void) Usage(progname,0);
if (strncmp(argv[1], "-help", 2) == 0)
(void) Usage(progname,0);
(void) strcpy(infile,argv[1]);
for (i=2; i<argc; i++) {
if (strncmp(argv[i], "-o", 2) == 0) {
strncpy(output_format,argv[i]+2,3);
} else if (strncmp(argv[i], "-i", 2) == 0) {
keep_normals = FALSE;
} else if (strncmp(argv[i], "-s", 2) == 0) {
do_rescale = TRUE;
if (argv[i+1][0] != '-') {
scale.x = atof(argv[++i]);
}
if (argv[i+1][0] != '-') {
scale.y = atof(argv[++i]);
} else {
scale.y = scale.x;
}
if (argv[i+1][0] != '-') {
scale.z = atof(argv[++i]);
} else {
scale.z = scale.y;
}
} else if (strncmp(argv[i], "-c", 2) == 0) {
do_cyl = TRUE;
} else if (strncmp(argv[i], "-t", 2) == 0) {
do_trans = TRUE;
if (!do_rescale) do_trans_first = TRUE;
if (argc > i) {
if (!isalpha(argv[i+1][1])) {
trans.x = atof(argv[++i]);
trans.y = trans.x;
trans.z = trans.y;
}
}
if (argc > i) {
if (!isalpha(argv[i+1][1])) {
trans.y = atof(argv[++i]);
trans.z = trans.y;
}
}
if (argc > i) {
if (!isalpha(argv[i+1][1])) {
trans.z = atof(argv[++i]);
}
}
} else {
(void) Usage(progname,0);
}
}
// Read the input file
tri_head = read_input (infile,FALSE,NULL);
// apply any transformations
// we should really do this like in stickkit - with a list of operations
if (do_trans_first) translate_nodes (trans);
if (do_rescale) rescale_nodes (scale);
if (do_trans && !do_trans_first) translate_nodes (trans);
if (do_cyl) remap_to_cylinder();
// Write triangles to stdout
(void) write_output (tri_head,output_format,keep_normals,argc,argv);
fprintf(stderr,"Done.\n");
exit(0);
}
/*
* Scale all nodes
*/
void rescale_nodes (VEC scale) {
node_ptr this_node;
// then, perturb each according to the normal
this_node = node_head;
while (this_node) {
this_node->loc.x *= scale.x;
this_node->loc.y *= scale.y;
this_node->loc.z *= scale.z;
this_node = this_node->next_node;
}
return;
}
/*
* Translate all nodes
*/
void translate_nodes (VEC trans) {
node_ptr this_node;
// then, perturb each according to the normal
this_node = node_head;
while (this_node) {
this_node->loc.x += trans.x;
this_node->loc.y += trans.y;
this_node->loc.z += trans.z;
this_node = this_node->next_node;
}
return;
}
/*
* Remap nodes to a cylinder
*
* Initial version assumes original +x direction (0..1) is new theta (0..2pi)
* and cylinder axis is +z
*/
void remap_to_cylinder () {
node_ptr this_node;
// then, perturb each according to the normal
this_node = node_head;
while (this_node) {
//float theta = atanf(this_node->loc.y, this_node->loc.x);
float theta = 2.0 * 3.14159265358979 * this_node->loc.x;
//float rad = sqrt(pow(this_node->loc.x,2) + pow(this_node->loc.x,2));
float rad = this_node->loc.y + 1.0 / (2.0 * 3.14159265358979);
this_node->loc.x = rad * cos(theta);
this_node->loc.y = rad * sin(theta);
this_node = this_node->next_node;
}
return;
}
/*
* This function writes basic usage information to stderr,
* and then quits. Too bad.
*/
int Usage(char progname[MAX_FN_LEN],int status) {
/* Usage for rockconvert */
static char **cpp, *help_message[] =
{
"where [-options] are one or more of the following: ",
" ",
" -okey specify output format, key= raw,rad,pov,obj,tin,rib,seg ",
" default = raw; surface normal vectors are not supported ",
" ",
" -s [x [y [z]]] ",
" scale geometry by the given x,y,z factors, default=1,1,1 ",
" ",
" -t [x [y [z]]] ",
" translate geometry by the given x,y,z, default=0,0,0 ",
" ",
" -ignore ignore normals in output (strips normals) ",
" ",
" -help (in place of infile) returns this help information ",
" ",
"The input file can be of .obj, .raw, .msh, or .tin format, and the program",
" requires the input file to use its valid 3-character filename extension ",
" ",
"Options may be abbreviated to an unambiguous length",
"Output is to stdout, so redirect it to a file using '>'",
" ",
"rockconvert converts tri meshes from one file format to another ",
" ",
"examples: ",
" rockconvert in.tin -oobj > out.obj ",
" Read in the file in.tin and write a Wavefront .obj format version ",
" ",
" rockconvert in.raw -s 2 -orad > out.rad ",
" Read in the input file and scale all nodes by 2.0 in x, y, and z; ",
" finally write the result in Radiance format ",
" ",
NULL
};
fprintf(stderr, "usage:\n %s infile [-options]\n\n", progname);
for (cpp = help_message; *cpp; cpp++) fprintf(stderr, "%s\n", *cpp);
fflush(stderr);
exit(status);
return(0);
}