curvedraw
diff src/app.cc @ 15:37ab3a4c02f8
merged
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 20 Dec 2015 09:06:04 +0200 |
parents | b625f0575d66 4da693339d99 |
children | 7f795f7fecd6 |
line diff
1.1 --- a/src/app.cc Thu Dec 17 16:41:42 2015 +0200 1.2 +++ b/src/app.cc Sun Dec 20 09:06:04 2015 +0200 1.3 @@ -7,6 +7,7 @@ 1.4 #include "app.h" 1.5 #include "curve.h" 1.6 #include "widgets.h" 1.7 +#include "curvefile.h" 1.8 1.9 enum SnapMode { 1.10 SNAP_NONE, 1.11 @@ -29,21 +30,24 @@ 1.12 static float grid_size = 1.0; 1.13 static SnapMode snap_mode; 1.14 1.15 +static bool show_bounds; 1.16 + 1.17 static std::vector<Curve*> curves; 1.18 static Curve *sel_curve; // selected curve being edited 1.19 static Curve *new_curve; // new curve being entered 1.20 static Curve *hover_curve; // curve the mouse is hovering over (click to select) 1.21 -static int sel_pidx = -1; // selected point of the selected or hovered-over curve 1.22 +static int sel_pidx = -1; // selected point of the selected curve 1.23 +static int hover_pidx = -1; // hovered over point 1.24 1.25 static Label *weight_label; // floating label for the cp weight 1.26 1.27 -#ifdef DRAW_MOUSE_POINTER 1.28 static Vector2 mouse_pointer; 1.29 -#endif 1.30 1.31 1.32 bool app_init(int argc, char **argv) 1.33 { 1.34 + glewInit(); 1.35 + 1.36 glEnable(GL_MULTISAMPLE); 1.37 glEnable(GL_CULL_FACE); 1.38 1.39 @@ -148,6 +152,20 @@ 1.40 int numpt = curve->size(); 1.41 int segm = numpt * 16; 1.42 1.43 + if(show_bounds) { 1.44 + Vector3 bmin, bmax; 1.45 + curve->get_bbox(&bmin, &bmax); 1.46 + 1.47 + glLineWidth(1.0); 1.48 + glColor3f(0, 1, 0); 1.49 + glBegin(GL_LINE_LOOP); 1.50 + glVertex2f(bmin.x, bmin.y); 1.51 + glVertex2f(bmax.x, bmin.y); 1.52 + glVertex2f(bmax.x, bmax.y); 1.53 + glVertex2f(bmin.x, bmax.y); 1.54 + glEnd(); 1.55 + } 1.56 + 1.57 glLineWidth(curve == hover_curve ? 4.0 : 2.0); 1.58 if(curve == sel_curve) { 1.59 glColor3f(0.3, 0.4, 1.0); 1.60 @@ -159,7 +177,7 @@ 1.61 glBegin(GL_LINE_STRIP); 1.62 for(int i=0; i<segm; i++) { 1.63 float t = (float)i / (float)(segm - 1); 1.64 - Vector2 v = curve->interpolate(t); 1.65 + Vector3 v = curve->interpolate(t); 1.66 glVertex2f(v.x, v.y); 1.67 } 1.68 glEnd(); 1.69 @@ -180,10 +198,23 @@ 1.70 glColor3f(0.2, 1.0, 0.2); 1.71 } 1.72 } 1.73 - Vector2 pt = curve->get_point(i); 1.74 + Vector2 pt = curve->get_point2(i); 1.75 glVertex2f(pt.x, pt.y); 1.76 } 1.77 glEnd(); 1.78 + 1.79 + // draw the projected mouse point on the selected curve 1.80 + /* 1.81 + if(curve == sel_curve) { 1.82 + Vector3 pp = curve->proj_point(Vector3(mouse_pointer.x, mouse_pointer.y, 0.0)); 1.83 + 1.84 + glPointSize(5.0); 1.85 + glBegin(GL_POINTS); 1.86 + glColor3f(1, 0.8, 0.2); 1.87 + glVertex2f(pp.x, pp.y); 1.88 + glEnd(); 1.89 + } 1.90 + */ 1.91 glPointSize(1.0); 1.92 } 1.93 1.94 @@ -215,40 +246,64 @@ 1.95 } 1.96 break; 1.97 1.98 - case 'l': 1.99 - case 'L': 1.100 + case '1': 1.101 + case '2': 1.102 + case '3': 1.103 if(sel_curve) { 1.104 - sel_curve->set_type(CURVE_LINEAR); 1.105 + sel_curve->set_type((CurveType)((int)CURVE_LINEAR + key - '1')); 1.106 post_redisplay(); 1.107 } 1.108 if(new_curve) { 1.109 - new_curve->set_type(CURVE_LINEAR); 1.110 + new_curve->set_type((CurveType)((int)CURVE_LINEAR + key - '1')); 1.111 post_redisplay(); 1.112 } 1.113 break; 1.114 1.115 case 'b': 1.116 case 'B': 1.117 + show_bounds = !show_bounds; 1.118 + post_redisplay(); 1.119 + break; 1.120 + 1.121 + case 'n': 1.122 + case 'N': 1.123 if(sel_curve) { 1.124 - sel_curve->set_type(CURVE_BSPLINE); 1.125 - post_redisplay(); 1.126 - } 1.127 - if(new_curve) { 1.128 - new_curve->set_type(CURVE_BSPLINE); 1.129 + sel_curve->normalize(); 1.130 post_redisplay(); 1.131 } 1.132 break; 1.133 1.134 - case 'h': 1.135 - case 'H': 1.136 - if(sel_curve) { 1.137 - sel_curve->set_type(CURVE_HERMITE); 1.138 - post_redisplay(); 1.139 + case 'e': 1.140 + case 'E': 1.141 + // TODO: GUI for filename at least 1.142 + if(!save_curves("test.curves", &curves[0], (int)curves.size())) { 1.143 + fprintf(stderr, "failed to export curves\n"); 1.144 } 1.145 - if(new_curve) { 1.146 - new_curve->set_type(CURVE_HERMITE); 1.147 - post_redisplay(); 1.148 + printf("exported %d curves\n", (int)curves.size()); 1.149 + break; 1.150 + 1.151 + case 'l': 1.152 + case 'L': 1.153 + { 1.154 + std::list<Curve*> clist = load_curves("test.curves"); 1.155 + if(clist.empty()) { 1.156 + fprintf(stderr, "failed to import curves\n"); 1.157 + } 1.158 + 1.159 + for(size_t i=0; i<curves.size(); i++) { 1.160 + delete curves[i]; 1.161 + } 1.162 + curves.clear(); 1.163 + 1.164 + int num = 0; 1.165 + std::list<Curve*>::iterator it = clist.begin(); 1.166 + while(it != clist.end()) { 1.167 + curves.push_back(*it++); 1.168 + ++num; 1.169 + } 1.170 + printf("imported %d curves\n", num); 1.171 } 1.172 + post_redisplay(); 1.173 break; 1.174 } 1.175 } 1.176 @@ -335,7 +390,7 @@ 1.177 int pidx = curves[i]->nearest_point(pos); 1.178 if(pidx == -1) continue; 1.179 1.180 - Vector2 cp = curves[i]->get_point(pidx); 1.181 + Vector2 cp = curves[i]->get_point2(pidx); 1.182 if((cp - pos).length_sq() < thres * thres) { 1.183 *curveret = curves[i]; 1.184 *pidxret = pidx; 1.185 @@ -347,6 +402,28 @@ 1.186 return false; 1.187 } 1.188 1.189 +static bool hit_test(const Vector2 &pos, Curve **curveret, int *pidxret) 1.190 +{ 1.191 + float thres = 0.02 / view_scale; 1.192 + 1.193 + if(point_hit_test(pos, curveret, pidxret)) { 1.194 + return true; 1.195 + } 1.196 + 1.197 + Vector3 pos3 = Vector3(pos.x, pos.y, 0.0f); 1.198 + for(size_t i=0; i<curves.size(); i++) { 1.199 + float x; 1.200 + if((x = curves[i]->distance_sq(pos3)) < thres * thres) { 1.201 + *curveret = curves[i]; 1.202 + *pidxret = -1; 1.203 + return true; 1.204 + } 1.205 + } 1.206 + *curveret = 0; 1.207 + *pidxret = -1; 1.208 + return false; 1.209 +} 1.210 + 1.211 static Vector2 snap(const Vector2 &p) 1.212 { 1.213 switch(snap_mode) { 1.214 @@ -407,10 +484,8 @@ 1.215 if(!dx && !dy) return; 1.216 1.217 Vector2 uv = pixel_to_uv(x, y); 1.218 -#ifdef DRAW_MOUSE_POINTER 1.219 mouse_pointer = uv; 1.220 - post_redisplay(); 1.221 -#endif 1.222 + //post_redisplay(); 1.223 1.224 /* when entering a new curve, have the last (extra) point following 1.225 * the mouse until it's entered by a click (see on_click). 1.226 @@ -422,7 +497,10 @@ 1.227 1.228 if(!new_curve && !bnstate) { 1.229 // not dragging, highlight curve under mouse 1.230 - point_hit_test(uv, &hover_curve, &sel_pidx); 1.231 + hit_test(uv, &hover_curve, &hover_pidx); 1.232 + if(hover_curve == sel_curve) { 1.233 + sel_pidx = hover_pidx; 1.234 + } 1.235 post_redisplay(); 1.236 1.237 } else { 1.238 @@ -482,6 +560,7 @@ 1.239 if(hover_curve) { 1.240 // if we're hovering: click selects 1.241 sel_curve = hover_curve; 1.242 + sel_pidx = hover_pidx; 1.243 hover_curve = 0; 1.244 } else if(sel_curve) { 1.245 // if we have a selected curve: click adds point (enter new_curve mode) 1.246 @@ -520,9 +599,11 @@ 1.247 // in selected curve mode: delete control point or unselect 1.248 Curve *hit_curve; 1.249 int hit_pidx; 1.250 - if(point_hit_test(uv, &hit_curve, &hit_pidx) && hit_curve == sel_curve) { 1.251 - hit_curve->remove_point(hit_pidx); 1.252 - sel_pidx = -1; 1.253 + if(hit_test(uv, &hit_curve, &hit_pidx) && hit_curve == sel_curve) { 1.254 + if(hit_pidx != -1) { 1.255 + hit_curve->remove_point(hit_pidx); 1.256 + sel_pidx = -1; 1.257 + } 1.258 } else { 1.259 sel_curve = 0; 1.260 sel_pidx = -1;