src/misc.cpp

changeset 493
16766ac1bbd9
parent 461
fbcc91ae1dd2
child 498
791c831c8020
equal deleted inserted replaced
492:e964085e6913 493:16766ac1bbd9
24 #include "gui.h" 24 #include "gui.h"
25 #include "dialogs.h" 25 #include "dialogs.h"
26 #include "ui_rotpoint.h" 26 #include "ui_rotpoint.h"
27 27
28 // Prime number table. 28 // Prime number table.
29 const ushort g_primes[NUM_PRIMES] = { 29 const ushort g_primes[NUM_PRIMES] =
30 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 30 { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
31 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 31 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
32 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 32 73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
33 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 33 127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
34 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 34 179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
35 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 35 233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
36 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 36 283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
37 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 37 353, 359, 367, 373, 379, 383, 389, 397, 401, 409,
38 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 38 419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
39 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 39 467, 479, 487, 491, 499, 503, 509, 521, 523, 541,
40 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 40 547, 557, 563, 569, 571, 577, 587, 593, 599, 601,
41 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 41 607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
42 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 42 661, 673, 677, 683, 691, 701, 709, 719, 727, 733,
43 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 43 739, 743, 751, 757, 761, 769, 773, 787, 797, 809,
44 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 44 811, 821, 823, 827, 829, 839, 853, 857, 859, 863,
45 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 45 877, 881, 883, 887, 907, 911, 919, 929, 937, 941,
46 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 46 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013,
47 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 47 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069,
48 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 48 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
49 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 49 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223,
50 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 50 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291,
51 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 51 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373,
52 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 52 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
53 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 53 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511,
54 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 54 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583,
55 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 55 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657,
56 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 56 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
57 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 57 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811,
58 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 58 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889,
59 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 59 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987,
60 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 60 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053,
61 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 61 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129,
62 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 62 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213,
63 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 63 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287,
64 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 64 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357,
65 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 65 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423,
66 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, 66 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531,
67 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 67 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617,
68 2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 68 2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687,
69 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 69 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741,
70 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, 70 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819,
71 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, 71 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903,
72 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 72 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999,
73 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 73 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079,
74 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 74 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181,
75 3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 75 3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257,
76 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 76 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331,
77 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 77 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413,
78 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 78 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511,
79 3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, 79 3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571,
80 }; 80 };
81 81
82 // ============================================================================= 82 // =============================================================================
83 // ----------------------------------------------------------------------------- 83 // -----------------------------------------------------------------------------
84 // Grid stuff 84 // Grid stuff
99 cfg (Int, edit_rotpoint, 0); 99 cfg (Int, edit_rotpoint, 0);
100 cfg (Float, edit_rotpoint_x, 0.0f); // TODO: make a VertexConfig and use it here 100 cfg (Float, edit_rotpoint_x, 0.0f); // TODO: make a VertexConfig and use it here
101 cfg (Float, edit_rotpoint_y, 0.0f); 101 cfg (Float, edit_rotpoint_y, 0.0f);
102 cfg (Float, edit_rotpoint_z, 0.0f); 102 cfg (Float, edit_rotpoint_z, 0.0f);
103 103
104 const gridinfo g_GridInfo[3] = { 104 const gridinfo g_GridInfo[3] =
105 { "Coarse", { &grid_coarse_x, &grid_coarse_y, &grid_coarse_z, &grid_coarse_angle }}, 105 { { "Coarse", { &grid_coarse_x, &grid_coarse_y, &grid_coarse_z, &grid_coarse_angle }},
106 { "Medium", { &grid_medium_x, &grid_medium_y, &grid_medium_z, &grid_medium_angle }}, 106 { "Medium", { &grid_medium_x, &grid_medium_y, &grid_medium_z, &grid_medium_angle }},
107 { "Fine", { &grid_fine_x, &grid_fine_y, &grid_fine_z, &grid_fine_angle }} 107 { "Fine", { &grid_fine_x, &grid_fine_y, &grid_fine_z, &grid_fine_angle }}
108 }; 108 };
109 109
110 // ============================================================================= 110 // =============================================================================
111 // Snap the given coordinate value on the current grid's given axis. 111 // Snap the given coordinate value on the current grid's given axis.
112 // ----------------------------------------------------------------------------- 112 // -----------------------------------------------------------------------------
113 double Grid::snap (double in, const Grid::Config axis) { 113 double Grid::snap (double in, const Grid::Config axis)
114 const double gridval = currentGrid().confs[axis]->value; 114 { const double gridval = currentGrid().confs[axis]->value;
115 const long mult = abs (in / gridval); 115 const long mult = abs (in / gridval);
116 const bool neg = (in < 0); 116 const bool neg = (in < 0);
117 double out = mult * gridval; 117 double out = mult * gridval;
118 118
119 if (abs<double> (in) - (mult * gridval) > gridval / 2) 119 if (abs<double> (in) - (mult * gridval) > gridval / 2)
120 out += gridval; 120 out += gridval;
121 121
122 if (neg && out != 0) 122 if (neg && out != 0)
123 out *= -1; 123 out *= -1;
124 124
125 return out; 125 return out;
126 } 126 }
127 127
128 // ============================================================================= 128 // =============================================================================
129 // Float to string. Removes trailing zeroes and is locale-independant. 129 // Float to string. Removes trailing zeroes and is locale-independant.
130 // TODO: Replace with QString::number() 130 // TODO: Replace with QString::number()
131 // ----------------------------------------------------------------------------- 131 // -----------------------------------------------------------------------------
132 str ftoa (double num) { 132 str ftoa (double num)
133 // Disable the locale first so that the decimal point will not 133 { // Disable the locale first so that the decimal point will not
134 // turn into anything weird (like commas) 134 // turn into anything weird (like commas)
135 setlocale (LC_NUMERIC, "C"); 135 setlocale (LC_NUMERIC, "C");
136 136
137 str rep; 137 str rep;
138 rep.sprintf ("%f", num); 138 rep.sprintf ("%f", num);
139 139
140 // Remove trailing zeroes 140 // Remove trailing zeroes
141 while (rep.right (1) == "0") 141 while (rep.right (1) == "0")
142 rep.chop (1); 142 rep.chop (1);
143 143
144 // If there were only zeroes in the decimal place, remove 144 // If there were only zeroes in the decimal place, remove
145 // the decimal point now. 145 // the decimal point now.
146 if (rep.right (1) == ".") 146 if (rep.right (1) == ".")
147 rep.chop (1); 147 rep.chop (1);
148 148
149 return rep; 149 return rep;
150 } 150 }
151 151
152 // ============================================================================= 152 // =============================================================================
153 // TODO: I guess Qt must have something like this stashed somewhere? 153 // TODO: I guess Qt must have something like this stashed somewhere?
154 // ----------------------------------------------------------------------------- 154 // -----------------------------------------------------------------------------
155 bool isNumber (const str& tok) { 155 bool isNumber (const str& tok)
156 bool gotDot = false; 156 { bool gotDot = false;
157 157
158 for (int i = 0; i < tok.length(); ++i) { 158 for (int i = 0; i < tok.length(); ++i)
159 const qchar c = tok[i]; 159 { const qchar c = tok[i];
160 160
161 // Allow leading hyphen for negatives 161 // Allow leading hyphen for negatives
162 if (i == 0 && c == '-') 162 if (i == 0 && c == '-')
163 continue; 163 continue;
164 164
165 // Check for decimal point 165 // Check for decimal point
166 if (!gotDot && c == '.') { 166 if (!gotDot && c == '.')
167 gotDot = true; 167 { gotDot = true;
168 continue; 168 continue;
169 } 169 }
170 170
171 if (c >= '0' && c <= '9') 171 if (c >= '0' && c <= '9')
172 continue; // Digit 172 continue; // Digit
173 173
174 // If the above cases didn't catch this character, it was 174 // If the above cases didn't catch this character, it was
175 // illegal and this is therefore not a number. 175 // illegal and this is therefore not a number.
176 return false; 176 return false;
177 } 177 }
178 178
179 return true; 179 return true;
180 } 180 }
181 181
182 // ============================================================================= 182 // =============================================================================
183 // ----------------------------------------------------------------------------- 183 // -----------------------------------------------------------------------------
184 void simplify (short& numer, short& denom) { 184 void simplify (short& numer, short& denom)
185 bool repeat; 185 { bool repeat;
186 186
187 do { 187 do
188 repeat = false; 188 { repeat = false;
189 189
190 for (ushort x = 0; x < NUM_PRIMES; x++) { 190 for (ushort x = 0; x < NUM_PRIMES; x++)
191 const ushort prime = g_primes[NUM_PRIMES - x - 1]; 191 { const ushort prime = g_primes[NUM_PRIMES - x - 1];
192 192
193 if (numer <= prime || denom <= prime) 193 if (numer <= prime || denom <= prime)
194 continue; 194 continue;
195 195
196 if ((numer % prime == 0) && (denom % prime == 0)) { 196 if ( (numer % prime == 0) && (denom % prime == 0))
197 numer /= prime; 197 { numer /= prime;
198 denom /= prime; 198 denom /= prime;
199 repeat = true; 199 repeat = true;
200 break; 200 break;
201 } 201 }
202 } 202 }
203 } while (repeat); 203 }
204 } 204 while (repeat);
205 205 }
206 // ============================================================================= 206
207 // ----------------------------------------------------------------------------- 207 // =============================================================================
208 vertex rotPoint (const List<LDObject*>& objs) { 208 // -----------------------------------------------------------------------------
209 LDBoundingBox box; 209 vertex rotPoint (const List<LDObject*>& objs)
210 210 { LDBoundingBox box;
211 switch (edit_rotpoint) { 211
212 case ObjectOrigin: 212 switch (edit_rotpoint)
213 // Calculate center vertex 213 { case ObjectOrigin:
214
215 // Calculate center vertex
214 for (LDObject * obj : objs) 216 for (LDObject * obj : objs)
215 if (obj->hasMatrix()) 217 if (obj->hasMatrix())
216 box << dynamic_cast<LDMatrixObject*>(obj)->position(); 218 box << dynamic_cast<LDMatrixObject*> (obj)->position();
217 else 219 else
218 box << obj; 220 box << obj;
219 221
220 return box.center(); 222 return box.center();
221 223
222 case WorldOrigin: 224 case WorldOrigin:
223 return g_origin; 225 return g_origin;
224 226
225 case CustomPoint: 227 case CustomPoint:
226 return vertex (edit_rotpoint_x, edit_rotpoint_y, edit_rotpoint_z); 228 return vertex (edit_rotpoint_x, edit_rotpoint_y, edit_rotpoint_z);
227 } 229 }
228 230
229 return vertex(); 231 return vertex();
230 } 232 }
231 233
232 // ============================================================================= 234 // =============================================================================
233 // ----------------------------------------------------------------------------- 235 // -----------------------------------------------------------------------------
234 void configRotationPoint() { 236 void configRotationPoint()
235 QDialog* dlg = new QDialog; 237 { QDialog* dlg = new QDialog;
236 Ui::RotPointUI ui; 238 Ui::RotPointUI ui;
237 ui.setupUi (dlg); 239 ui.setupUi (dlg);
238 240
239 switch (edit_rotpoint) { 241 switch (edit_rotpoint)
240 case ObjectOrigin: 242 { case ObjectOrigin:
241 ui.objectPoint->setChecked (true); 243 ui.objectPoint->setChecked (true);
242 break; 244 break;
243 245
244 case WorldOrigin: 246 case WorldOrigin:
245 ui.worldPoint->setChecked (true); 247 ui.worldPoint->setChecked (true);
246 break; 248 break;
247 249
248 case CustomPoint: 250 case CustomPoint:
249 ui.customPoint->setChecked (true); 251 ui.customPoint->setChecked (true);
250 break; 252 break;
251 } 253 }
252 254
253 ui.customX->setValue (edit_rotpoint_x); 255 ui.customX->setValue (edit_rotpoint_x);
254 ui.customY->setValue (edit_rotpoint_y); 256 ui.customY->setValue (edit_rotpoint_y);
255 ui.customZ->setValue (edit_rotpoint_z); 257 ui.customZ->setValue (edit_rotpoint_z);
256 258
257 if (!dlg->exec()) 259 if (!dlg->exec())
258 return; 260 return;
259 261
260 edit_rotpoint = 262 edit_rotpoint =
261 (ui.objectPoint->isChecked()) ? ObjectOrigin : 263 (ui.objectPoint->isChecked()) ? ObjectOrigin :
262 (ui.worldPoint->isChecked()) ? WorldOrigin : 264 (ui.worldPoint->isChecked()) ? WorldOrigin :
263 CustomPoint; 265 CustomPoint;
264 266
265 edit_rotpoint_x = ui.customX->value(); 267 edit_rotpoint_x = ui.customX->value();
266 edit_rotpoint_y = ui.customY->value(); 268 edit_rotpoint_y = ui.customY->value();
267 edit_rotpoint_z = ui.customZ->value(); 269 edit_rotpoint_z = ui.customZ->value();
268 } 270 }
269 271
270 // ============================================================================= 272 // =============================================================================
271 // ----------------------------------------------------------------------------- 273 // -----------------------------------------------------------------------------
272 str join (initlist<StringFormatArg> vals, str delim) { 274 str join (initlist<StringFormatArg> vals, str delim)
273 QStringList list; 275 { QStringList list;
274 for (const StringFormatArg& arg : vals) 276
277 for (const StringFormatArg & arg : vals)
275 list << arg.value(); 278 list << arg.value();
276 279
277 return list.join (delim); 280 return list.join (delim);
278 } 281 }
279 282
280 // ============================================================================= 283 // =============================================================================
281 // TODO: I'm quite sure Qt has this covered as well. 284 // TODO: I'm quite sure Qt has this covered as well.
282 // ----------------------------------------------------------------------------- 285 // -----------------------------------------------------------------------------
283 double atof (str val) { 286 double atof (str val)
284 // Disable the locale while parsing the line or atof's behavior changes 287 { // Disable the locale while parsing the line or atof's behavior changes
285 // between locales (i.e. fails to read decimals properly). That is 288 // between locales (i.e. fails to read decimals properly). That is
286 // quite undesired... 289 // quite undesired...
287 setlocale (LC_NUMERIC, "C"); 290 setlocale (LC_NUMERIC, "C");
288 291
289 char* buf = new char[val.length()]; 292 char* buf = new char[val.length()];
290 char* bufptr = &buf[0]; 293 char* bufptr = &buf[0];
291 294
292 for (qchar& c : val) 295 for (QChar& c : val)
293 *bufptr++ = c.toLatin1(); 296 *bufptr++ = c.toLatin1();
297
294 *bufptr = '\0'; 298 *bufptr = '\0';
295 299
296 double fval = atof (buf); 300 double fval = atof (buf);
297 delete[] buf; 301 delete[] buf;
298 return fval; 302 return fval;
299 } 303 }

mercurial