curvedraw

annotate src/curvefile.cc @ 10:95fada20c638

foo
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 19 Dec 2015 17:40:27 +0200
parents 8bf96e11ed1f
children 099fd7adb900
rev   line source
nuclear@6 1 #include <stdlib.h>
nuclear@8 2 #include <ctype.h>
nuclear@8 3 #include <string>
nuclear@6 4 #include "curvefile.h"
nuclear@6 5
nuclear@6 6 static bool save_curve(FILE *fp, const Curve *curve);
nuclear@6 7
nuclear@6 8 bool save_curves(const char *fname, const Curve * const *curves, int count)
nuclear@6 9 {
nuclear@6 10 FILE *fp = fopen(fname, "wb");
nuclear@6 11 if(!fp) return false;
nuclear@6 12
nuclear@6 13 bool res = save_curves(fp, curves, count);
nuclear@6 14 fclose(fp);
nuclear@6 15 return res;
nuclear@6 16 }
nuclear@6 17
nuclear@6 18 bool save_curves(FILE *fp, const Curve * const *curves, int count)
nuclear@6 19 {
nuclear@8 20 fprintf(stderr, "GCURVES\n");
nuclear@6 21
nuclear@6 22 for(int i=0; i<count; i++) {
nuclear@6 23 if(!save_curve(fp, curves[i])) {
nuclear@6 24 return false;
nuclear@6 25 }
nuclear@6 26 }
nuclear@6 27 return true;
nuclear@6 28 }
nuclear@6 29
nuclear@6 30 static const char *curve_type_str(CurveType type)
nuclear@6 31 {
nuclear@6 32 switch(type) {
nuclear@6 33 case CURVE_LINEAR:
nuclear@6 34 return "polyline";
nuclear@6 35 case CURVE_HERMITE:
nuclear@6 36 return "hermite";
nuclear@6 37 case CURVE_BSPLINE:
nuclear@6 38 return "bspline";
nuclear@6 39 }
nuclear@6 40 abort();
nuclear@6 41 }
nuclear@6 42
nuclear@6 43 static bool save_curve(FILE *fp, const Curve *curve)
nuclear@6 44 {
nuclear@6 45 fprintf(fp, "curve {\n");
nuclear@6 46 fprintf(fp, " type %s\n", curve_type_str(curve->get_type()));
nuclear@6 47 fprintf(fp, " cpcount %d\n", curve->size());
nuclear@6 48 for(int i=0; i<curve->size(); i++) {
nuclear@6 49 Vector3 cp = curve->get_homo_point(i);
nuclear@6 50 fprintf(fp, " cp %g %g %g\n", cp.x, cp.y, cp.z);
nuclear@6 51 }
nuclear@6 52 fprintf(fp, "}\n");
nuclear@6 53 return true;
nuclear@6 54 }
nuclear@6 55
nuclear@10 56 std::list<Curve*> load_curves(const char *fname)
nuclear@6 57 {
nuclear@10 58 std::list<Curve*> res;
nuclear@8 59 FILE *fp = fopen(fname, "r");
nuclear@10 60 if(!fp) return res;
nuclear@6 61
nuclear@10 62 res = load_curves(fp);
nuclear@6 63 fclose(fp);
nuclear@6 64 return res;
nuclear@6 65 }
nuclear@6 66
nuclear@8 67 static std::string next_token(FILE *fp)
nuclear@8 68 {
nuclear@8 69 std::string s;
nuclear@8 70 int c;
nuclear@8 71 while((c = fgetc(fp)) != -1 && isspace(c)); // skip whitespace
nuclear@8 72 if(feof(fp)) return s;
nuclear@8 73 while((c = fgetc(fp)) != -1 && !isspace(c)) {
nuclear@8 74 s.push_back(c);
nuclear@8 75 }
nuclear@8 76 return s;
nuclear@8 77 }
nuclear@8 78
nuclear@8 79 static bool expect_str(FILE *fp, const char *s)
nuclear@8 80 {
nuclear@8 81 std::string tok = next_token(fp);
nuclear@8 82 if(tok != std::string(s)) {
nuclear@8 83 if(!(tok.empty() && feof(fp))) {
nuclear@8 84 fprintf(stderr, "expected: %s\n", s);
nuclear@8 85 }
nuclear@8 86 return false;
nuclear@8 87 }
nuclear@8 88 return true;
nuclear@8 89 }
nuclear@8 90
nuclear@8 91 static bool expect_float(FILE *fp, float *ret)
nuclear@8 92 {
nuclear@8 93 std::string tok = next_token(fp);
nuclear@8 94 const char *cs = tok.c_str();
nuclear@8 95 char *endp;
nuclear@8 96 *ret = strtod(cs, &endp);
nuclear@8 97 if(endp != cs + tok.length()) {
nuclear@8 98 if(!(tok.empty() && feof(fp))) {
nuclear@8 99 fprintf(stderr, "number expected\n");
nuclear@8 100 }
nuclear@8 101 return false;
nuclear@8 102 }
nuclear@8 103 return true;
nuclear@8 104 }
nuclear@8 105
nuclear@8 106 static bool expect_int(FILE *fp, int *ret)
nuclear@8 107 {
nuclear@8 108 std::string tok = next_token(fp);
nuclear@8 109 const char *cs = tok.c_str();
nuclear@8 110 char *endp;
nuclear@8 111 *ret = strtol(cs, &endp, 0);
nuclear@8 112 if(endp != cs + tok.length()) {
nuclear@8 113 if(!(tok.empty() && feof(fp))) {
nuclear@8 114 fprintf(stderr, "integer expected\n");
nuclear@8 115 }
nuclear@8 116 return false;
nuclear@8 117 }
nuclear@8 118 return true;
nuclear@8 119 }
nuclear@8 120
nuclear@8 121 static Curve *curve_block(FILE *fp)
nuclear@8 122 {
nuclear@8 123 if(!expect_str(fp, "curve") || !expect_str(fp, "{")) {
nuclear@8 124 return 0;
nuclear@8 125 }
nuclear@8 126
nuclear@8 127 Curve *curve = new Curve;
nuclear@8 128 int cpcount = -1;
nuclear@8 129 std::string tok;
nuclear@8 130 while(!(tok = next_token(fp)).empty() && tok != "}") {
nuclear@8 131 if(tok == "cpcount") {
nuclear@8 132 if(cpcount != -1 || !expect_int(fp, &cpcount) || cpcount <= 0) {
nuclear@8 133 goto err;
nuclear@8 134 }
nuclear@8 135 } else if(tok == "type") {
nuclear@8 136 tok = next_token(fp);
nuclear@8 137 if(tok == "polyline") {
nuclear@8 138 curve->set_type(CURVE_LINEAR);
nuclear@8 139 } else if(tok == "hermite") {
nuclear@8 140 curve->set_type(CURVE_HERMITE);
nuclear@8 141 } else if(tok == "bspline") {
nuclear@8 142 curve->set_type(CURVE_BSPLINE);
nuclear@8 143 } else {
nuclear@8 144 goto err;
nuclear@8 145 }
nuclear@8 146 } else {
nuclear@8 147 if(!expect_str(fp, "cp")) {
nuclear@8 148 goto err;
nuclear@8 149 }
nuclear@8 150 Vector3 cp;
nuclear@8 151 for(int i=0; i<3; i++) {
nuclear@8 152 if(!expect_float(fp, &cp[i])) {
nuclear@8 153 goto err;
nuclear@8 154 }
nuclear@8 155 }
nuclear@8 156 curve->add_point(Vector2(cp.x, cp.y), cp.z);
nuclear@8 157 }
nuclear@8 158 }
nuclear@8 159
nuclear@8 160 if(curve->size() != cpcount) {
nuclear@8 161 fprintf(stderr, "warning: curve cpcount was %d, but read %d control points\n", cpcount, curve->size());
nuclear@8 162 }
nuclear@8 163
nuclear@8 164 return curve;
nuclear@8 165 err:
nuclear@8 166 fprintf(stderr, "failed to parse curve block\n");
nuclear@8 167 delete curve;
nuclear@8 168 return 0;
nuclear@8 169 }
nuclear@8 170
nuclear@10 171 std::list<Curve*> load_curves(FILE *fp)
nuclear@6 172 {
nuclear@10 173 std::list<Curve*> curves;
nuclear@8 174 if(!expect_str(fp, "GCURVES")) {
nuclear@8 175 fprintf(stderr, "load_curves: failed to load, invalid file format\n");
nuclear@10 176 return curves;
nuclear@8 177 }
nuclear@8 178
nuclear@8 179 Curve *curve;
nuclear@8 180 while((curve = curve_block(fp))) {
nuclear@8 181 curves.push_back(curve);
nuclear@8 182 }
nuclear@8 183
nuclear@8 184 int ncurves = (int)curves.size();
nuclear@8 185 if(!feof(fp)) {
nuclear@10 186 std::list<Curve*>::iterator it = curves.begin();
nuclear@10 187 while(it != curves.end()) {
nuclear@10 188 delete *it++;
nuclear@8 189 }
nuclear@10 190 return curves;
nuclear@8 191 }
nuclear@8 192
nuclear@10 193 return curves;
nuclear@6 194 }
nuclear@6 195