]> Shamusworld >> Repos - architektonas/blob - src/base/grid.cpp
Bugfixes related to removing Snapper class.
[architektonas] / src / base / grid.cpp
1 // grid.cpp
2 //
3 // Part of the Architektonas Project
4 // Originally part of QCad Community Edition by Andrew Mustun
5 // Extensively rewritten and refactored by James L. Hammons
6 // Portions copyright (C) 2001-2003 RibbonSoft
7 // Copyright (C) 2010 Underground Software
8 // See the README and GPLv2 files for licensing and warranty information
9 //
10 // JLH = James L. Hammons <jlhamm@acm.org>
11 //
12 // Who  When        What
13 // ---  ----------  -----------------------------------------------------------
14 // JLH  05/21/2010  Added this text. :-)
15 //
16
17 #include "grid.h"
18
19 #include "drawing.h"
20 #include "graphicview.h"
21 #include "settings.h"
22 #include "units.h"
23 #include "vector.h"
24
25 #warning "!!! Clean out all references to RS_GraphicView here and in header !!!"
26 /**
27  * Constructor.
28  */
29 Grid::Grid(GraphicView * gv): graphicView(gv), pt(NULL), number(0),
30         metaX(NULL), numMetaX(0), metaY(NULL), numMetaY(0)
31 {
32 }
33
34 /**
35  * Destructor.
36  */
37 Grid::~Grid()
38 {
39         if (pt != NULL)
40                 delete[] pt;
41
42         if (metaX != NULL)
43                 delete[] metaX;
44
45         if (metaY != NULL)
46                 delete[] metaY;
47 }
48
49 /**
50  * Updates the grid point array.
51  */
52 void Grid::update()
53 {
54         DEBUG->print("Grid::update");
55
56         if (!graphicView->isGridOn())
57                 return;
58
59         Drawing * graphic = graphicView->getGraphic();
60
61         // auto scale grid?
62         settings.beginGroup("Appearance");
63         bool scaleGrid = settings.value("ScaleGrid", true).toBool();
64         int minGridSpacing = settings.value("MinGridSpacing", 10).toInt();
65         settings.endGroup();
66
67         // get grid setting
68         Vector userGrid;
69
70         if (graphic != NULL)
71                 userGrid = graphic->getVariableVector("$GRIDUNIT", Vector(-1.0, -1.0));
72
73         // delete old grid:
74         if (pt != NULL)
75         {
76                 delete[] pt;
77                 pt = NULL;
78         }
79
80         if (metaX != NULL)
81         {
82                 delete[] metaX;
83                 metaX = NULL;
84         }
85
86         if (metaY != NULL)
87         {
88                 delete[] metaY;
89                 metaY = NULL;
90         }
91
92         number = 0;
93         numMetaX = 0;
94         numMetaY = 0;
95
96         DEBUG->print("Grid::update: 001");
97
98         // find out unit:
99         RS2::Unit unit = RS2::None;
100         RS2::LinearFormat format = RS2::Decimal;
101
102         if (graphic != NULL)
103         {
104                 unit = graphic->getUnit();
105                 format = graphic->getLinearFormat();
106         }
107
108         Vector gridWidth;
109         Vector metaGridWidth;
110
111         DEBUG->print("Grid::update: 002");
112
113         // init grid spacing:
114         // metric grid:
115         if (Units::isMetric(unit) || unit == RS2::None
116                 || format == RS2::Decimal || format == RS2::Engineering)
117         {
118                 if (userGrid.x > 0.0)
119                         gridWidth.x = userGrid.x;
120                 else
121                         gridWidth.x = 0.000001;
122
123                 if (userGrid.y > 0.0)
124                         gridWidth.y = userGrid.y;
125                 else
126                         gridWidth.y = 0.000001;
127
128                 DEBUG->print("Grid::update: 003");
129
130                 // auto scale grid
131                 if (scaleGrid)
132                 {
133                         while (graphicView->toGuiDX(gridWidth.x) < minGridSpacing)
134                                 gridWidth.x *= 10;
135
136                         while (graphicView->toGuiDY(gridWidth.y) < minGridSpacing)
137                                 gridWidth.y *= 10;
138                 }
139
140                 metaGridWidth.x = gridWidth.x * 10;
141                 metaGridWidth.y = gridWidth.y * 10;
142
143                 DEBUG->print("Grid::update: 004");
144         }
145         // imperial grid:
146         else
147         {
148                 DEBUG->print("Grid::update: 005");
149
150                 if (userGrid.x > 0.0)
151                         gridWidth.x = userGrid.x;
152                 else
153                         gridWidth.x = 1.0 / 1024.0;
154
155                 if (userGrid.y > 0.0)
156                         gridWidth.y = userGrid.y;
157                 else
158                         gridWidth.y = 1.0 / 1024.0;
159
160                 DEBUG->print("Grid::update: 006");
161
162                 if (unit == RS2::Inch)
163                 {
164                         DEBUG->print("Grid::update: 007");
165
166                         // auto scale grid
167                         if (scaleGrid)
168                         {
169                                 while (graphicView->toGuiDX(gridWidth.x) < minGridSpacing)
170                                 {
171                                         if (Math::round(gridWidth.x) >= 36)
172                                         {
173                                                 gridWidth.x *= 2;
174                                         }
175                                         else if (Math::round(gridWidth.x) >= 12)
176                                         {
177                                                 gridWidth.x *= 3;
178                                         }
179                                         else if (Math::round(gridWidth.x) >= 4)
180                                         {
181                                                 gridWidth.x *= 3;
182                                         }
183                                         else if (Math::round(gridWidth.x) >= 1)
184                                         {
185                                                 gridWidth.x *= 2;
186                                         }
187                                         else
188                                         {
189                                                 gridWidth.x*=2;
190                                         }
191                                 }
192
193                                 while (graphicView->toGuiDY(gridWidth.y) < minGridSpacing)
194                                 {
195                                         if (Math::round(gridWidth.y) >= 36)
196                                         {
197                                                 gridWidth.y *= 2;
198                                         }
199                                         else if (Math::round(gridWidth.y) >= 12)
200                                         {
201                                                 gridWidth.y *= 3;
202                                         }
203                                         else if (Math::round(gridWidth.y) >= 4)
204                                         {
205                                                 gridWidth.y *= 3;
206                                         }
207                                         else if (Math::round(gridWidth.y) >= 1)
208                                         {
209                                                 gridWidth.y *= 2;
210                                         }
211                                         else
212                                         {
213                                                 gridWidth.y *= 2;
214                                         }
215                                 }
216                         }
217
218                         DEBUG->print("Grid::update: 008");
219
220                         // metagrid X shows inches..
221                         metaGridWidth.x = 1.0;
222
223                         if (graphicView->toGuiDX(metaGridWidth.x) < minGridSpacing * 2)
224                         {
225                                 // .. or feet
226                                 metaGridWidth.x = 12.0;
227
228                                 // .. or yards
229                                 if (graphicView->toGuiDX(metaGridWidth.x) < minGridSpacing * 2)
230                                 {
231                                         metaGridWidth.x = 36.0;
232
233                                         // .. or miles (not really..)
234                                         //if (graphicView->toGuiDX(metaGridWidth.x)<20) {
235                                         //    metaGridWidth.x = 63360.0;
236                                         //}
237
238                                         // .. or nothing
239                                         if (graphicView->toGuiDX(metaGridWidth.x) < minGridSpacing * 2)
240                                                 metaGridWidth.x = -1.0;
241
242                                 }
243                         }
244
245                         DEBUG->print("Grid::update: 009");
246
247                         // metagrid Y shows inches..
248                         metaGridWidth.y = 1.0;
249
250                         if (graphicView->toGuiDY(metaGridWidth.y) < minGridSpacing * 2)
251                         {
252                                 // .. or feet
253                                 metaGridWidth.y = 12.0;
254
255                                 // .. or yards
256                                 if (graphicView->toGuiDY(metaGridWidth.y) < minGridSpacing * 2)
257                                 {
258                                         metaGridWidth.y = 36.0;
259
260                                         // .. or miles (not really..)
261                                         //if (graphicView->toGuiDY(metaGridWidth.y)<20) {
262                                         //    metaGridWidth.y = 63360.0;
263                                         //}
264
265                                         // .. or nothing
266                                         if (graphicView->toGuiDY(metaGridWidth.y) < minGridSpacing * 2)
267                                         {
268                                                 metaGridWidth.y = -1.0;
269                                         }
270
271                                 }
272                         }
273
274                         DEBUG->print("Grid::update: 010");
275                 }
276                 else
277                 {
278                         DEBUG->print("Grid::update: 011");
279
280                         if (scaleGrid)
281                         {
282                                 while (graphicView->toGuiDX(gridWidth.x) < minGridSpacing)
283                                 {
284                                         gridWidth.x *= 2;
285                                 }
286
287                                 metaGridWidth.x = -1.0;
288
289                                 while (graphicView->toGuiDY(gridWidth.y) < minGridSpacing)
290                                 {
291                                         gridWidth.y *= 2;
292                                 }
293
294                                 metaGridWidth.y = -1.0;
295                         }
296                         DEBUG->print("Grid::update: 012");
297                 }
298                 //gridWidth.y = gridWidth.x;
299                 //metaGridWidth.y = metaGridWidth.x;
300         }
301
302         DEBUG->print("Grid::update: 013");
303
304         // for grid info:
305         spacing = gridWidth.x;
306         metaSpacing = metaGridWidth.x;
307
308         if (gridWidth.x > 1.0e-6 && gridWidth.y > 1.0e-6
309                 && graphicView->toGuiDX(gridWidth.x) > 2
310                 && graphicView->toGuiDY(gridWidth.y) > 2)
311         {
312                 // find grid boundaries
313                 double left = (int)(graphicView->toGraphX(0) / gridWidth.x)
314                         * gridWidth.x;
315                 double right = (int)(graphicView->toGraphX(graphicView->getWidth())
316                         / gridWidth.x) * gridWidth.x;
317                 double top = (int)(graphicView->toGraphY(0)
318                         / gridWidth.y) * gridWidth.y;
319                 double bottom =
320                         (int)(graphicView->toGraphY(graphicView->getHeight())
321                         / gridWidth.y) * gridWidth.y;
322
323
324                 left -= gridWidth.x;
325                 right += gridWidth.x;
326                 top += gridWidth.y;
327                 bottom -= gridWidth.y;
328
329                 // calculate number of visible grid points
330                 int numberX = (Math::round((right-left) / gridWidth.x) + 1);
331                 int numberY = (Math::round((top-bottom) / gridWidth.y) + 1);
332                 number = numberX * numberY;
333
334                 DEBUG->print("Grid::update: 014");
335
336                 // create grid array:
337                 if (number > 0 && number < 1000000)
338                 {
339                         pt = new Vector[number];
340
341                         int i=0;
342                         for(int y=0; y<numberY; ++y)
343                         {
344                                 for(int x=0; x<numberX; ++x)
345                                 {
346                                         pt[i++] = Vector(left + x * gridWidth.x, bottom + y * gridWidth.y);
347                                 }
348                         }
349                 }
350                 else
351                 {
352                         number = 0;
353                         pt = NULL;
354                 }
355
356                 DEBUG->print("Grid::update: 015");
357         }
358
359         // find meta grid boundaries
360         if (metaGridWidth.x > 1.0e-6 && metaGridWidth.y > 1.0e-6
361                 && graphicView->toGuiDX(metaGridWidth.x) > 2
362                 && graphicView->toGuiDY(metaGridWidth.y) > 2)
363         {
364                 double mleft = (int)(graphicView->toGraphX(0)
365                         / metaGridWidth.x) * metaGridWidth.x;
366                 double mright = (int)(graphicView->toGraphX(graphicView->getWidth())
367                         / metaGridWidth.x) * metaGridWidth.x;
368                 double mtop = (int)(graphicView->toGraphY(0)
369                         / metaGridWidth.y) * metaGridWidth.y;
370                 double mbottom = (int)(graphicView->toGraphY(graphicView->getHeight())
371                         / metaGridWidth.y) * metaGridWidth.y;
372
373                 mleft -= metaGridWidth.x;
374                 mright += metaGridWidth.x;
375                 mtop += metaGridWidth.y;
376                 mbottom -= metaGridWidth.y;
377
378                 // calculate number of visible meta grid lines:
379                 numMetaX = (Math::round((mright - mleft) / metaGridWidth.x) + 1);
380                 numMetaY = (Math::round((mtop - mbottom) / metaGridWidth.y) + 1);
381
382                 if (numMetaX > 0 && numMetaY > 0)
383                 {
384                         // create meta grid arrays:
385                         metaX = new double[numMetaX];
386                         metaY = new double[numMetaY];
387
388                         int i = 0;
389
390                         for(int x=0; x<numMetaX; ++x)
391                                 metaX[i++] = mleft + x * metaGridWidth.x;
392
393                         i = 0;
394
395                         for(int y=0; y<numMetaY; ++y)
396                                 metaY[i++] = mbottom + y * metaGridWidth.y;
397                 }
398                 else
399                 {
400                         numMetaX = 0;
401                         metaX = NULL;
402                         numMetaY = 0;
403                         metaY = NULL;
404                 }
405         }
406
407         DEBUG->print("Grid::update: OK");
408 }
409
410 /**
411  * @return Array of all visible grid points.
412  */
413 Vector * Grid::getPoints()
414 {
415         return pt;
416 }
417
418 /**
419  * @return Number of visible grid points.
420  */
421 int Grid::count()
422 {
423         return number;
424 }
425
426 /**
427  * @return Grid info for status widget.
428  */
429 QString Grid::getInfo()
430 {
431         return QString("%1 / %2").arg(spacing).arg(metaSpacing);
432 }
433
434 /**
435  * @return Meta grid positions in X.
436  */
437 double * Grid::getMetaX()
438 {
439         return metaX;
440 }
441
442 /**
443  * @return Number of visible meta grid lines in X.
444  */
445 int Grid::countMetaX()
446 {
447         return numMetaX;
448 }
449
450 /**
451 * @return Meta grid positions in Y.
452 */
453 double * Grid::getMetaY()
454 {
455         return metaY;
456 }
457
458 /**
459 * @return Number of visible meta grid lines in Y.
460 */
461 int Grid::countMetaY()
462 {
463         return numMetaY;
464 }