#define PROG_NAME "SplineToWire4" #define PROG_DESC "???" #define PROG_VERS "1.0" #define SplineToWire4_C_COPYRIGHT \ "" #define PROG_INFO \ "" \ " " /* Given control points of a cubic spline curve, generates sample points along it. Writes the sample points as camera positions in the format expected by the "Wire4" - Interactive 4D Wireframe Display Program (".w4"). Also writes a plain text file with one point per line (preceded by its integer ID). -Include the option "renderInterval" ( between [1-10]) for generate spacing among configurations. Last Modification by stolfi 06-08-2000 */ #include #include #include #define _GNU_SOURCE #include #include #include // BSplineApproximation; TYPE double Row3I = ARRAY [0..2] OF INTEGER; double double = double; typedef struct Options_t { char *outFile; /* Output file name prefix */ uint ncp; /* Number of control points. */ cp: REF r4_vec_t; /* Control points for spline. */ bool_t tips; /* TRUE includes the endpoints. */ double normalize; /* If nonzero, normalize From-To vectors to this length. */ uint renderInterval; /* Subsampling ratio for camera positions. */ uint samplesPerArc; /* Number of samples per spline arc (for Wire4 plotting). */ To4: r4_t; /* Look at point */ Up4: r4_t; /* Head-up point */ Over4: r4_t; /* Hyperhead-up point */ } <* FATAL Wr.Failure, Thread.Alerted, OSError.E); void WriteColor(FILE *wr, *c: Row3I) /* Write colors in RGB mode */ { Mis.WriteInt(wr,c[0]); fprintf(wr," "); Mis.WriteInt(wr,c[1]); fprintf(wr," "); Mis.WriteInt(wr,c[2]); } /* END WriteColor */ Options_t *GetOptions(int argc, char **argv); int main(int argc, char **argv) { Options_t *o = GetOptions(argc, argv); char *topo_cmt = jsprintf("Created by %s on %s", PROG_NAME, Today()); /* Random_t coins = MakeRandomSource(4615); */ ??? cmt = "Made by SplineToWire4 on " & Today() & "\n"; ??? w4 = FileWr.Open(o->outFile & ".w4"); ??? txt = FileWr.Open(o->outFile & ".from4"); { WriteCmt(w4,o,cmt); WriteComments(txt,o,cmt); WriteWire4Header(w4); SamplePath(o,w4,txt); fclose(w4); fclose(txt); return 0; } void WriteComments(FILE *wr, *o: Options_t; cmt: char *) { filefmt_write_comment(wr,cmt,'#'); fprintf(wr, "# control points :\n"); for (i = 0; i < o->ncp; i++) { fprintf(wr, "# "); Mis.WritePoint(wr, o->cp[i]); fprintf(wr, "\n"); } fprintf(wr, "\n"); } /* END WriteComments */ void WriteWire4Header(wr: Wr.T) { fprintf(wr, "DegreeRing@{Edge->?}s"); fprintf(wr," 0"); fprintf(wr,"\nDepthCueLevels 10"); fprintf(wr,"\nFogDensity 0.5"); fprintf(wr,"\n"); fprintf(wr, "\nFrom4: +9 00 00 00"); fprintf(wr, "\nTo4 : 00 00 00 00"); fprintf(wr, "\nUp4 : 00 00 +1 00"); fprintf(wr, "\nOver4: 00 00 00 +1"); fprintf(wr, "\nVangle4: 30"); fprintf(wr, "\n"); fprintf(wr, "\nFrom3: +9 00 00"); fprintf(wr, "\nTo3 : 00 00 00"); fprintf(wr, "\nUp3 : 00 00 +1"); fprintf(wr, "\nVangle3: 30"); } /* END WriteWire4Header */ PROCEDURE SamplePath(*o: Options_t; w4: Wr.T; txt: Wr.T) VAR uint nv,ne; /* Number of nodes and edges in the curve spline. */ uint kv; /* Node counter */ vcolor : Row3I = Row3I{100,100,100}; ecolor : Row3I = Row3I{0,255,255}; vradius : REAL = 1.0; eradius : REAL = 1.0; { void SampleSplineArc(a, b, c, r4_t *d, np: uint) { /* To amend the first control point */ ??? tini = ((double)-2*np); ??? ta = ((double) -np); ??? tb = ((double) 0); ??? tc = ((double) np); ??? td = ((double) 2*np); ??? tfin = ((double) 3*np) DO ReportInterval(kv; with (kv+np-1); for (j = 0; j < np; j++) { ??? t = FLOAT(j, double)); with( double Q = BSplineApproximation(t, tini, ta,a, tb,b, tc,c, td,d, tfin) ){ ProcessSample(Q) } } } } SampleSplineArc; void ReportInterval(ini, fin: uint) { fprintf(stderr, "Interpoling between [ " & Fmt.Int(ini) & "-" \ Fmt.Int(fin) & "]\n"); } ReportInterval; void ProcessSample(Q: r4_t) { if (o->normalize > 0.0) { Q = r4_Scale(o->normalize, r4_Dir(r4_Sub(Q,o->To4))) }; WritePoint4DForWire4(Q,vcolor,vradius); if (kv % o->renderInterval == 0) { WritePoint4DAsText(Q,kv); }; kv++ } ProcessSample; void WriteCoord(FILE *wr, x: double) { fprintf(wr, Fmt.Pad(Fmt.LongReal(x, Fmt.Style.Fix, prec = 4), 7)); } WriteCoord; void WritePoint4DForWire4(*c: r4_t; vcolor: Row3I; vradius: REAL) { WriteCoord(w4,c[0]); fprintf(w4, " "); WriteCoord(w4,c[1]); fprintf(w4, " "); WriteCoord(w4,c[2]); fprintf(w4, " "); WriteCoord(w4,c[3]); fprintf(w4, " : "); WriteColor(w4, vcolor); fprintf(w4, " : "); Mis.WriteRadius(w4, vradius); fprintf(w4, "\n"); } WritePoint4DForWire4; void WritePoint4DAsText(*c: r4_t; uint i) { fprintf(txt, " " & Fmt.Int(i) & " "); WriteCoord(txt,c[0]); fprintf(txt, " "); WriteCoord(txt,c[1]); fprintf(txt, " "); WriteCoord(txt,c[2]); fprintf(txt, " "); WriteCoord(txt,c[3]); fprintf(txt, "\n"); } WritePoint4DAsText; { /* compute the number of nodes */ nv = (o->ncp - 3)*o->samplesPerArc; if (o->tips) { nv = nv + 4*o->samplesPerArc + 1 } fprintf(w4, "\n\nNodeList : "); fprintf(w4, Fmt.Int(nv+5) & "\n"); kv = 0; if (o->tips) { SampleSplineArc(o->cp[0], o->cp[0], o->cp[0], o->cp[1], o->samplesPerArc); SampleSplineArc(o->cp[0], o->cp[0], o->cp[1], o->cp[2], o->samplesPerArc); } for (i = 0; i <= (o->ncp-4); i++) { SampleSplineArc(o->cp[i], o->cp[i+1], o->cp[i+2], o->cp[i+3], o->samplesPerArc); } if (o->tips) { SampleSplineArc(o->cp[o->ncp-3], o->cp[o->ncp-2], o->cp[o->ncp-1], o->cp[o->ncp-1], o->samplesPerArc); SampleSplineArc(o->cp[o->ncp-2], o->cp[o->ncp-1], o->cp[o->ncp-1], o->cp[o->ncp-1], o->samplesPerArc); ProcessSample(o->cp[o->ncp-1]) } /* reference axis nodes */ fprintf(w4, " 0 0 0 0 : 255 255 255 : 0\n"); fprintf(w4, " 1 0 0 0 : 255 255 255 : 0\n"); fprintf(w4, " 0 1 0 0 : 255 255 255 : 0\n"); fprintf(w4, " 0 0 1 0 : 255 255 255 : 0\n"); fprintf(w4, " 0 0 0 1 : 255 255 255 : 0\n"); fprintf(w4, "\n"); ne = nv - 1; fprintf(w4, "\n@{Edge->?}List " & Fmt.Int(ne+4) & ":\n"); for (i = 0; i < ne; i++) { fprintf(w4, Fmt.Pad(Fmt.Int(i), 4) & " " & Fmt.Pad(Fmt.Int(i+1),4)); fprintf(w4, " : "); /* color */ WriteColor(w4, ecolor); fprintf(w4, " : "); Mis.WriteRadius(w4, eradius); fprintf(w4, "\n"); } /* reference axis @{edge->?}s */ fprintf(w4, " " & Fmt.Int(nv) & " " & Fmt.Int(nv+1)); fprintf(w4, " : 125 125 125 : 1\n"); fprintf(w4, " " & Fmt.Int(nv) & " " & Fmt.Int(nv+2)); fprintf(w4, " : 125 125 125 : 1\n"); fprintf(w4, " " & Fmt.Int(nv) & " " & Fmt.Int(nv+3)); fprintf(w4, " : 125 125 125 : 1\n"); fprintf(w4, " " & Fmt.Int(nv) & " " & Fmt.Int(nv+4)); fprintf(w4, " : 125 125 125 : 1\n"); fprintf(w4, "\nWallList 0\n"); fclose(w4); } } /* END SamplePath */ Options_t *GetOptions(int argc, char **argv) Options_t *o = (Options_t *)malloc(sizeof(Options_t)); { argparser_t *pp = argparser_new(stderr, argc, argv); argparser_set_help(pp, PROG_NAME " version " PROG_VERS ", usage:\n" PROG_HELP); argparser_set_info(pp, PROG_INFO); argparser_process_help_info_options(pp); argparser_get_keyword(pp, "-outFile"); o->outFile = argparser_get_next(pp); argparser_get_keyword(pp, "-ncp"); o->ncp = argparser_get_next_int(pp, 4,100); o->cp = r4_vec_new(o->ncp); for (i = 0; i < o->ncp; i++) { for (j = 0; j < 4; j++) { o->cp[i,j] = pp.getNextLongReal(-100.0, 100.0); } } o->tips = argparser_keyword_present(pp, "-tips"); if ((argparser_keyword_present(pp, "-normalize"))) { o->normalize = pp.getNextLongReal(1.0d-10,1.0d+10); } else { o->normalize = 0.0; } if ((argparser_keyword_present(pp, "-samplesPerArc"))) { o->samplesPerArc = argparser_get_next_int(pp, 1,100); } else { o->samplesPerArc = 10; } if ((argparser_keyword_present(pp, "-renderInterval"))) { o->renderInterval = argparser_get_next_int(pp, 1,100); } else { o->renderInterval = 10; } argparser_finish(pp); ----------------------------------- #define _HELP \ fprintf(stderr, "Usage: SplineToWire4 \\\n" \ " -outFile \\\n" \ " [ -normalize ] \\\n" \ " -ncp \\\n" \ " [ ] \\\n" \ " ............................... \\\n" \ " [ ] \\\n" \ " [ -tips ] \\\n" \ " [ -samplesPerArc ] \\\n" \ " [ -renderInterval ]\n"); END¦ } } return o; } /* END GetOptions */ /* end SplineToWire4 */