X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=output.c;h=e37aa7c21775c3383381b856685fd7ed1be6370b;hb=fcb05a81ecead2dcd3375c6d4ceb528ca6e181c0;hp=39a25356b9a9b352a03891c7f2337cb44b0ca3ec;hpb=4f9769b263b5e16c9c94ed3aba3829678a504261;p=moebius2.git diff --git a/output.c b/output.c index 39a2535..e37aa7c 100644 --- a/output.c +++ b/output.c @@ -53,16 +53,16 @@ * *B \ / *B | \ / *A \ / *A \ / *A * \ / : | \ / . ' \ / \ / * _______ *C _____ :_|___ *C' __________ *C ___________ *C _________ - * /\ : | 3 /\. 0 /\ /\ - * / \ : | / \ ` . / \ / \ + * /\ : | 3 /\ 0 /\ /\ + * / \ : | / \ / \ / \ * : * . . : . . . . . . * : - * \ / : | \ / . ' \ / \ / - * _______ *C _____ :_|___ *C' __________ *C ___________ *C _________ - * /\ : | 3 /\. 0 /\ /\ - * / \ : | / \ ` . / \ / \ + * \ / : | \ / \ / \ / + * _______ *C _____ :_|___ *C ___________ *C ___________ *C _________ + * /\ : | 3 /\ 0 /\ /\ + * / \ : | / \ / \ / \ * *A / \ *A | /4 5\ *B / \ *B / \ *B * / \ 1: / / \ / \ / \ * / \ :/ / \ / \ / \ @@ -101,7 +101,7 @@ * G: Each F is the mean of those two adjacent Es with the * same angle in their respective Ps. * - * The outtriangles are: + * The outfacets are: * * For each non-rim vertex on each side, the six triangles formed by * its C and the surrounding A's and B's. @@ -130,6 +130,12 @@ typedef struct { #define NG 10 #define NDEF (NG*2+1) +#define OUTPUT_ARRAY_LIST(DO_OUTPUT_ARRAY) \ + DO_OUTPUT_ARRAY(ovAB) \ + DO_OUTPUT_ARRAY(ovC) \ + DO_OUTPUT_ARRAY(ovDEF) \ + DO_OUTPUT_ARRAY(ovG) + static OutVertex ovAB[N][2][2]; /* indices: vertex to W, A=0 B=1, side */ static OutVertex ovC[N][2]; static OutVertex ovDEF[X][2][NDEF]; /* x, !!y, angle */ @@ -140,8 +146,8 @@ static Vertices in; static double thick; /* in input units */ static double scale; -static void outtriangle(int rev, const OutVertex *a, - const OutVertex *b, const OutVertex *c); +static void outfacet(int rev, const OutVertex *a, + const OutVertex *b, const OutVertex *c); static void normalise_thick(double a[D3]) { /* multiplies a by a scalar so that its magnitude is thick */ @@ -161,23 +167,30 @@ static void triangle_normal(double normal[D3], const double a[D3], } static OutVertex *invertex2outvertexab(int v0, int e, int side) { - int vref, ab; + int vref, vchk, ab; switch (e) { - case 0: vref= v0 ; ab=0; break; - case 1: vref=EDGE_END2(v0,2); ab=1; break; - case 2: vref=EDGE_END2(v0,3); ab=0; break; - case 3: vref=EDGE_END2(v0,3); ab=1; break; - case 4: vref=EDGE_END2(v0,4); ab=0; break; - case 5: vref= v0 ; ab=1; break; + case 0: vref=v0; vchk=EDGE_END2(v0,1); ab=0; break; + case 1: vref= vchk=EDGE_END2(v0,2); ab=1; break; + case 2: vref=EDGE_END2(v0,3); vchk=EDGE_END2(v0,2); ab=0; break; + case 3: vref=EDGE_END2(v0,3); vchk=EDGE_END2(v0,4); ab=1; break; + case 4: vref= vchk=EDGE_END2(v0,4); ab=0; break; + case 5: vref=v0; vchk=EDGE_END2(v0,5); ab=1; break; default: abort(); } - if (vref<0) return 0; - int sw= VERTICES_SPAN_JOIN_P(v0,vref); + if (vchk<0) return 0; + int sw= vertices_span_join_p(v0,vref); return &ovAB[vref][ab^sw][side^sw]; } /*---------- output vertices ----------*/ +#define Ok(ov, value) ((ov).p[k]= outvertex_coord_check(value)) + +static double outvertex_coord_check(double value) { + assert(-10 < value && value < 10); + return value; +} + static void compute_outvertices(void) { int v0,k,side,ab,x,y; @@ -185,38 +198,37 @@ static void compute_outvertices(void) { for (ab=0; ab<2; ab++) { int v1= EDGE_END2(v0, ab?5:0); int v2= EDGE_END2(v0, ab?0:1); - if (v1<0 || v2<0) { - K ovAB[v0][ab][0].p[k]= ovAB[v0][ab][1].p[k]= NAN; + if (v1<0 || v2<0) continue; - } double normal[D3], centroid[D3]; triangle_normal(normal, in[v0],in[v1],in[v2]); normalise_thick(normal); K centroid[k]= (in[v0][k] + in[v1][k] + in[v2][k]) / 3.0; - K ovAB[v0][ab][0].p[k]= centroid[k] + normal[k]; - K ovAB[v0][ab][1].p[k]= centroid[k] - normal[k]; + K Ok(ovAB[v0][ab][0], centroid[k] + normal[k]); + K Ok(ovAB[v0][ab][1], centroid[k] - normal[k]); } } FOR_VERTEX(v0) { int vw= EDGE_END2(v0,3); int vnw= EDGE_END2(v0,2); int vsw= EDGE_END2(v0,4); - if (vnw<0 || vsw<0 || vw<0) { - K ovC[v0][0].p[k]= ovC[v0][1].p[k]= NAN; + if (vnw<0 || vsw<0 || vw<0) continue; - } FOR_SIDE { double adjust[D3]; int e; K adjust[k]= 0; FOR_VPEDGE(e) { OutVertex *ovab= invertex2outvertexab(v0,e,side); - K adjust[k] += ovab->p[k]; + K { + assert(!isnan(ovab->p[k])); + adjust[k] += ovab->p[k]; + } } K adjust[k] /= 6; K adjust[k] -= in[v0][k]; normalise_thick(adjust); - K ovC[v0][side].p[k]= in[v0][k] + adjust[k]; + K Ok(ovC[v0][side], in[v0][k] + adjust[k]); } } FOR_RIM_VERTEX(y,x,v0) { @@ -252,10 +264,10 @@ static void compute_outvertices(void) { for (around=0; around= 0); int around; for (around=0; aroundp[k])); + } + outfacets_around(side, cd, 6,ab); } } } -/*---------- transformation (scale and perhaps shift) ----------*/ +/*---------- operations on very output vertex ----------*/ + +#define DO_OUTPUT_ARRAY_OUTVERTEX_ARRAY(fn,ovX) \ + ((fn)(sizeof((ovX))/sizeof(OutVertex), (OutVertex*)(ovX))) -static void scaleshift_outvertex_array(int n, OutVertex ovX[n]) { +static void blank_outvertex_array(int n, OutVertex ovX[n]) { + int i, k; + for (i=0; i= -1e3 && d <= 1e3); + +#if BYTE_ORDER==BIG_ENDIAN union { uint8_t b[4]; ieee754single f; } value; value.f= d; int i; for (i=3; i>=0; i--) WR(value.b[i]); -#elif defined(LITTLE_ENDIAN) +#elif BYTE_ORDER==LITTLE_ENDIAN ieee754single f= d; WR(f); #else @@ -384,20 +413,31 @@ static void wf(double d) { #endif } -static uint32_t nouttriangles; -static uint32_t nouttriangles_counted; +static uint32_t noutfacets; +static uint32_t noutfacets_counted; -static void outtriangle(int rev, const OutVertex *a, - const OutVertex *b, const OutVertex *c) { - if (rev) { outtriangle(0, c,b,a); return; } - nouttriangles++; - if (!~nouttriangles_counted) return; +static void outfacet(int rev, const OutVertex *a, + const OutVertex *b, const OutVertex *c) { + if (rev) { outfacet(0, c,b,a); return; } double normal[D3]; int k; + K { + assert(!isnan(a->p[k])); + assert(!isnan(b->p[k])); + assert(!isnan(c->p[k])); + } + triangle_normal(normal, a->p, b->p, c->p); double multby= 1/magnD(normal); + + if (multby > 1e6) + return; + + noutfacets++; + if (!~noutfacets_counted) return; + K normal[k] *= multby; K wf(normal[k]); @@ -411,19 +451,19 @@ static void outtriangle(int rev, const OutVertex *a, static void write_file(void) { static const char header[80]= "#!/usr/bin/meshlab\n" "binary STL file\n"; - if (isatty(1)) fail("will not write binary stl to tty!"); + if (isatty(1)) fail("will not write binary stl to tty!\n"); WR(header); - nouttriangles_counted=~(uint32_t)0; - nouttriangles=0; - outtriangles(); - WR(nouttriangles); + noutfacets_counted=~(uint32_t)0; + noutfacets=0; + outfacets(); + WR(noutfacets); - nouttriangles_counted= nouttriangles; - nouttriangles=0; - outtriangles(); - assert(nouttriangles == nouttriangles_counted); + noutfacets_counted= noutfacets; + noutfacets=0; + outfacets(); + assert(noutfacets == noutfacets_counted); if (fflush(stdout)) diee("fflush stdout"); } @@ -441,8 +481,9 @@ int main(int argc, const char *const *argv) { errno= 0; r= fread(&in,sizeof(in),1,stdin); if (r!=1) diee("fread"); + blank_outvertices(); compute_outvertices(); - scaleshift_outvertices(); + transform_outvertices(); write_file(); if (fclose(stdout)) diee("fclose stdout"); return 0;