-
Notifications
You must be signed in to change notification settings - Fork 3
/
obj2mesh.c
123 lines (121 loc) · 3.94 KB
/
obj2mesh.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
// gcc -O3 -DHAVE_ZLIB obj2mesh.c meshify.c quadric.c base64.c bwlabel.c radixsort.c -o obj2mesh -lz -lm
// obj2mesh dragon.obj reduced.obj
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
#include <string.h>
#include <unistd.h>
#include "meshify.h"
#include "quadric.h"
#if defined(_OPENMP)
#include <omp.h>
#endif
#ifdef HAVE_ZLIB
#include <zlib.h>
#endif
void read_obj(const char* filename, vec3d **verts, vec3i **tris, int* nvert, int* ntri){
//printf ( "Loading Objects %s ... \n",filename);
FILE* fn;
if(filename==NULL) return ;
if((char)filename[0]==0) return ;
if ((fn = fopen(filename, "rb")) == NULL) {
printf ( "File %s not found!\n" ,filename );
return;
}
*ntri = 0;
int tCapacity = 65536 * 16;
*tris = (vec3i *) malloc(tCapacity * sizeof(vec3i));
vec3i *ts = *tris;
*nvert = 0;
int vCapacity = 65536 * 16;
*verts = (vec3d *) malloc(vCapacity * sizeof(vec3d));
vec3d *vs = *verts;
char line[1000];
memset ( line,0,1000 );
int vertex_cnt = 0;
while(fgets( line, 1000, fn ) != NULL) {
vec3d v;
if (( line[0] == 'v' ) && ( line[1] == ' ' )) {
if(sscanf(line,"v %lf %lf %lf", &v.x, &v.y, &v.z)==3) {
if (*nvert >= vCapacity) {
vCapacity = round (vCapacity * 1.5);
*verts = (vec3d *)realloc(*verts,vCapacity*sizeof(vec3d));
vs = *verts;
}
vs[*nvert] = v;
*nvert = *nvert + 1;
}
}
vec3i t;
if ( line[0] == 'f' ) {
if(sscanf(line,"f %d %d %d", &t.x, &t.y, &t.z)==3) {
if (*ntri >= tCapacity) {
tCapacity = round (tCapacity * 1.5);
*tris = (vec3i *)realloc(*tris,tCapacity*sizeof(vec3i));
ts = *tris;
}
t = (vec3i){ .x = t.x-1, .y = t.y-1, .z = t.z-1 };
ts[*ntri] = t;
*ntri = *ntri + 1;
}
}
}
fclose(fn);
*verts = (vec3d *)realloc(*verts,*nvert*sizeof(vec3d));
*tris = (vec3i *)realloc(*tris,*ntri*sizeof(vec3i));
} // read_obj()
int main(int argc,char **argv) {
double agressiveness = 7.0;
double reduceFraction = 0.5;
int smoothIter = 0;
int quality = 1;
bool verbose = false;
if (argc < 3) {
printf("Converts a NIfTI voxelwise image to triangulated mesh.\n");
printf("Usage: %s [options] niftiname meshname\n",argv[0]);
printf("Options\n");
printf(" -q v quality (0=lossy, 1=lossy then losslesss, default %d)\n", quality);
printf(" -r v reduction factor (default %g)\n", reduceFraction);
printf(" -s v smoothing iterations (default %d)\n", smoothIter);
printf(" -v v verbose (0=silent, 1=verbose, default %d)\n", verbose);
printf("mesh extension sets format (.gii, .mz3, .obj, .ply, .pial, .stl, .vtk)\n");
printf("Example: '%s dragon.obj small.obj'\n",argv[0]);
printf("Example: '%s -v 1 -r 0.1 dragon.obj smaller.gii'\n",argv[0]);
printf("Example: '%s -s 30 dragon.obj smoother.gii'\n",argv[0]);
exit(-1);
}
for (int i=1;i<argc;i++) {
if (strcmp(argv[i],"-q") == 0)
quality = atoi(argv[i+1]);
if (strcmp(argv[i],"-r") == 0)
reduceFraction = atof(argv[i+1]);
if (strcmp(argv[i],"-s") == 0)
smoothIter = atoi(argv[i+1]);
if (strcmp(argv[i],"-v") == 0)
verbose = atoi(argv[i+1]);
}
vec3d *verts = NULL;
vec3i *tris = NULL;
int nvert;
int ntri;
read_obj(argv[argc-2], &verts, &tris, &nvert, &ntri);
int startTri = ntri;
int startVert = nvert;
int target_count = round((float)ntri * reduceFraction);
double startTime = clockMsec();
if (smoothIter > 0) {
laplacian_smoothHC(verts, tris, nvert, ntri, 0.1, 0.5, smoothIter, true);
if (verbose)
printf("%d smoothing iterations: %ld ms\n", smoothIter, timediff(startTime, clockMsec()));
startTime = clockMsec();
}
quadric_simplify_mesh(&verts, &tris, &nvert, &ntri, target_count, agressiveness, verbose, (quality > 0));
if (verbose)
printf("simplify: %ld ms\n", timediff(startTime, clockMsec()));
if (verbose)
printf("simplify vertices %d->%d triangles: %d->%d (r = %g)\n", startVert, nvert, startTri, ntri, (float)ntri / (float) startTri);
save_mesh(argv[argc-1], tris, verts, ntri, nvert, true);
free(tris);
free(verts);
}