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