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