30 #include "misc/documentPointer.cc" |
30 #include "misc/documentPointer.cc" |
31 #include "misc/ringFinder.cc" |
31 #include "misc/ringFinder.cc" |
32 |
32 |
33 // Prime number table. |
33 // Prime number table. |
34 const int g_primes[NUM_PRIMES] = |
34 const int g_primes[NUM_PRIMES] = |
35 { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, |
35 { |
|
36 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, |
36 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, |
37 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, |
37 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, |
38 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, |
38 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, |
39 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, |
39 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, |
40 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, |
40 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, |
41 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, |
83 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, |
84 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, |
84 3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, |
85 3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, |
85 }; |
86 }; |
86 |
87 |
87 static const int32 g_e10[] = |
88 static const int32 g_e10[] = |
88 { 1, |
89 { |
|
90 1, |
89 10, |
91 10, |
90 100, |
92 100, |
91 1000, |
93 1000, |
92 10000, |
94 10000, |
93 100000, |
95 100000, |
117 cfg (Float, edit_rotpoint_x, 0.0f); // TODO: make a VertexConfig and use it here |
119 cfg (Float, edit_rotpoint_x, 0.0f); // TODO: make a VertexConfig and use it here |
118 cfg (Float, edit_rotpoint_y, 0.0f); |
120 cfg (Float, edit_rotpoint_y, 0.0f); |
119 cfg (Float, edit_rotpoint_z, 0.0f); |
121 cfg (Float, edit_rotpoint_z, 0.0f); |
120 |
122 |
121 const gridinfo g_GridInfo[3] = |
123 const gridinfo g_GridInfo[3] = |
122 { { "Coarse", { &grid_coarse_x, &grid_coarse_y, &grid_coarse_z, &grid_coarse_angle }}, |
124 { |
|
125 { "Coarse", { &grid_coarse_x, &grid_coarse_y, &grid_coarse_z, &grid_coarse_angle }}, |
123 { "Medium", { &grid_medium_x, &grid_medium_y, &grid_medium_z, &grid_medium_angle }}, |
126 { "Medium", { &grid_medium_x, &grid_medium_y, &grid_medium_z, &grid_medium_angle }}, |
124 { "Fine", { &grid_fine_x, &grid_fine_y, &grid_fine_z, &grid_fine_angle }} |
127 { "Fine", { &grid_fine_x, &grid_fine_y, &grid_fine_z, &grid_fine_angle }} |
125 }; |
128 }; |
126 |
129 |
127 // ============================================================================= |
130 // ============================================================================= |
128 // Snap the given coordinate value on the current grid's given axis. |
131 // Snap the given coordinate value on the current grid's given axis. |
129 // ----------------------------------------------------------------------------- |
132 // ----------------------------------------------------------------------------- |
130 double Grid::snap (double in, const Grid::Config axis) |
133 double Grid::snap (double in, const Grid::Config axis) |
131 { const double gridval = *currentGrid().confs[axis]; |
134 { |
|
135 const double gridval = *currentGrid().confs[axis]; |
132 const long mult = abs (in / gridval); |
136 const long mult = abs (in / gridval); |
133 const bool neg = (in < 0); |
137 const bool neg = (in < 0); |
134 double out = mult * gridval; |
138 double out = mult * gridval; |
135 |
139 |
136 if (abs<double> (in) - (mult * gridval) > gridval / 2) |
140 if (abs<double> (in) - (mult * gridval) > gridval / 2) |
143 } |
147 } |
144 |
148 |
145 // ============================================================================= |
149 // ============================================================================= |
146 // ----------------------------------------------------------------------------- |
150 // ----------------------------------------------------------------------------- |
147 bool numeric (const str& tok) |
151 bool numeric (const str& tok) |
148 { bool gotDot = false; |
152 { |
|
153 bool gotDot = false; |
149 |
154 |
150 for (int i = 0; i < tok.length(); ++i) |
155 for (int i = 0; i < tok.length(); ++i) |
151 { const QChar c = tok[i]; |
156 { |
|
157 const QChar c = tok[i]; |
152 |
158 |
153 // Allow leading hyphen for negatives |
159 // Allow leading hyphen for negatives |
154 if (i == 0 && c == '-') |
160 if (i == 0 && c == '-') |
155 continue; |
161 continue; |
156 |
162 |
157 // Check for decimal point |
163 // Check for decimal point |
158 if (!gotDot && c == '.') |
164 if (!gotDot && c == '.') |
159 { gotDot = true; |
165 { |
|
166 gotDot = true; |
160 continue; |
167 continue; |
161 } |
168 } |
162 |
169 |
163 if (c >= '0' && c <= '9') |
170 if (c >= '0' && c <= '9') |
164 continue; // Digit |
171 continue; // Digit |
172 } |
179 } |
173 |
180 |
174 // ============================================================================= |
181 // ============================================================================= |
175 // ----------------------------------------------------------------------------- |
182 // ----------------------------------------------------------------------------- |
176 void simplify (int& numer, int& denom) |
183 void simplify (int& numer, int& denom) |
177 { bool repeat; |
184 { |
|
185 bool repeat; |
178 |
186 |
179 do |
187 do |
180 { repeat = false; |
188 { |
|
189 repeat = false; |
181 |
190 |
182 for (int x = 0; x < NUM_PRIMES; x++) |
191 for (int x = 0; x < NUM_PRIMES; x++) |
183 { const int prime = g_primes[NUM_PRIMES - x - 1]; |
192 { |
|
193 const int prime = g_primes[NUM_PRIMES - x - 1]; |
184 |
194 |
185 if (numer <= prime || denom <= prime) |
195 if (numer <= prime || denom <= prime) |
186 continue; |
196 continue; |
187 |
197 |
188 if ( (numer % prime == 0) && (denom % prime == 0)) |
198 if ( (numer % prime == 0) && (denom % prime == 0)) |
189 { numer /= prime; |
199 { |
|
200 numer /= prime; |
190 denom /= prime; |
201 denom /= prime; |
191 repeat = true; |
202 repeat = true; |
192 break; |
203 break; |
193 } |
204 } |
194 } |
205 } |
197 } |
208 } |
198 |
209 |
199 // ============================================================================= |
210 // ============================================================================= |
200 // ----------------------------------------------------------------------------- |
211 // ----------------------------------------------------------------------------- |
201 vertex rotPoint (const QList<LDObject*>& objs) |
212 vertex rotPoint (const QList<LDObject*>& objs) |
202 { LDBoundingBox box; |
213 { |
|
214 LDBoundingBox box; |
203 |
215 |
204 switch (edit_rotpoint) |
216 switch (edit_rotpoint) |
205 { case ObjectOrigin: |
217 { |
206 { // Calculate center vertex |
218 case ObjectOrigin: |
|
219 { |
|
220 // Calculate center vertex |
207 for (LDObject* obj : objs) |
221 for (LDObject* obj : objs) |
208 if (obj->hasMatrix()) |
222 if (obj->hasMatrix()) |
209 box << dynamic_cast<LDMatrixObject*> (obj)->getPosition(); |
223 box << dynamic_cast<LDMatrixObject*> (obj)->getPosition(); |
210 else |
224 else |
211 box << obj; |
225 box << obj; |
212 |
226 |
213 return box.center(); |
227 return box.center(); |
214 } |
228 } |
215 |
229 |
216 case WorldOrigin: |
230 case WorldOrigin: |
217 { return g_origin; |
231 { |
|
232 return g_origin; |
218 } |
233 } |
219 |
234 |
220 case CustomPoint: |
235 case CustomPoint: |
221 { return vertex (edit_rotpoint_x, edit_rotpoint_y, edit_rotpoint_z); |
236 { |
|
237 return vertex (edit_rotpoint_x, edit_rotpoint_y, edit_rotpoint_z); |
222 } |
238 } |
223 } |
239 } |
224 |
240 |
225 return vertex(); |
241 return vertex(); |
226 } |
242 } |
227 |
243 |
228 // ============================================================================= |
244 // ============================================================================= |
229 // ----------------------------------------------------------------------------- |
245 // ----------------------------------------------------------------------------- |
230 void configRotationPoint() |
246 void configRotationPoint() |
231 { QDialog* dlg = new QDialog; |
247 { |
|
248 QDialog* dlg = new QDialog; |
232 Ui::RotPointUI ui; |
249 Ui::RotPointUI ui; |
233 ui.setupUi (dlg); |
250 ui.setupUi (dlg); |
234 |
251 |
235 switch (edit_rotpoint) |
252 switch (edit_rotpoint) |
236 { case ObjectOrigin: |
253 { |
|
254 case ObjectOrigin: |
237 ui.objectPoint->setChecked (true); |
255 ui.objectPoint->setChecked (true); |
238 break; |
256 break; |
239 |
257 |
240 case WorldOrigin: |
258 case WorldOrigin: |
241 ui.worldPoint->setChecked (true); |
259 ui.worldPoint->setChecked (true); |
264 } |
282 } |
265 |
283 |
266 // ============================================================================= |
284 // ============================================================================= |
267 // ----------------------------------------------------------------------------- |
285 // ----------------------------------------------------------------------------- |
268 str join (initlist<StringFormatArg> vals, str delim) |
286 str join (initlist<StringFormatArg> vals, str delim) |
269 { QStringList list; |
287 { |
|
288 QStringList list; |
270 |
289 |
271 for (const StringFormatArg& arg : vals) |
290 for (const StringFormatArg& arg : vals) |
272 list << arg.value(); |
291 list << arg.value(); |
273 |
292 |
274 return list.join (delim); |
293 return list.join (delim); |
275 } |
294 } |
276 |
295 |
277 // ============================================================================= |
296 // ============================================================================= |
278 // ----------------------------------------------------------------------------- |
297 // ----------------------------------------------------------------------------- |
279 void roundToDecimals (double& a, int decimals) |
298 void roundToDecimals (double& a, int decimals) |
280 { assert (decimals >= 0 && decimals < (signed) (sizeof g_e10 / sizeof *g_e10)); |
299 { |
|
300 assert (decimals >= 0 && decimals < (signed) (sizeof g_e10 / sizeof *g_e10)); |
281 a = round (a * g_e10[decimals]) / g_e10[decimals]; |
301 a = round (a * g_e10[decimals]) / g_e10[decimals]; |
282 } |
302 } |
283 |
303 |
284 // ============================================================================= |
304 // ============================================================================= |
285 // ----------------------------------------------------------------------------- |
305 // ----------------------------------------------------------------------------- |
286 InvokationDeferer* g_invokationDeferer = new InvokationDeferer(); |
306 InvokationDeferer* g_invokationDeferer = new InvokationDeferer(); |
287 |
307 |
288 InvokationDeferer::InvokationDeferer (QObject* parent) : QObject (parent) |
308 InvokationDeferer::InvokationDeferer (QObject* parent) : QObject (parent) |
289 { connect (this, SIGNAL (functionAdded()), this, SLOT (invokeFunctions()), |
309 { |
|
310 connect (this, SIGNAL (functionAdded()), this, SLOT (invokeFunctions()), |
290 Qt::QueuedConnection); |
311 Qt::QueuedConnection); |
291 } |
312 } |
292 |
313 |
293 void InvokationDeferer::addFunctionCall (InvokationDeferer::FunctionType func) |
314 void InvokationDeferer::addFunctionCall (InvokationDeferer::FunctionType func) |
294 { m_funcs << func; |
315 { |
|
316 m_funcs << func; |
295 removeDuplicates (m_funcs); |
317 removeDuplicates (m_funcs); |
296 emit functionAdded(); |
318 emit functionAdded(); |
297 } |
319 } |
298 |
320 |
299 void InvokationDeferer::invokeFunctions() |
321 void InvokationDeferer::invokeFunctions() |
300 { for (FunctionType func : m_funcs) |
322 { |
|
323 for (FunctionType func : m_funcs) |
301 (*func)(); |
324 (*func)(); |
302 |
325 |
303 m_funcs.clear(); |
326 m_funcs.clear(); |
304 } |
327 } |
305 |
328 |
306 void invokeLater (InvokationDeferer::FunctionType func) |
329 void invokeLater (InvokationDeferer::FunctionType func) |
307 { g_invokationDeferer->addFunctionCall (func); |
330 { |
308 } |
331 g_invokationDeferer->addFunctionCall (func); |
|
332 } |