| 1 | // |
|---|
| 2 | // gfxcore.h |
|---|
| 3 | // |
|---|
| 4 | // Core drawing code for Aven. |
|---|
| 5 | // |
|---|
| 6 | // Copyright (C) 2000-2001, Mark R. Shinwell. |
|---|
| 7 | // Copyright (C) 2001-2002,2004,2005 Olly Betts |
|---|
| 8 | // |
|---|
| 9 | // This program is free software; you can redistribute it and/or modify |
|---|
| 10 | // it under the terms of the GNU General Public License as published by |
|---|
| 11 | // the Free Software Foundation; either version 2 of the License, or |
|---|
| 12 | // (at your option) any later version. |
|---|
| 13 | // |
|---|
| 14 | // This program is distributed in the hope that it will be useful, |
|---|
| 15 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 16 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 17 | // GNU General Public License for more details. |
|---|
| 18 | // |
|---|
| 19 | // You should have received a copy of the GNU General Public License |
|---|
| 20 | // along with this program; if not, write to the Free Software |
|---|
| 21 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|---|
| 22 | // |
|---|
| 23 | |
|---|
| 24 | #ifndef gfxcore_h |
|---|
| 25 | #define gfxcore_h |
|---|
| 26 | |
|---|
| 27 | #include <float.h> |
|---|
| 28 | |
|---|
| 29 | #include "quaternion.h" |
|---|
| 30 | #include "wx.h" |
|---|
| 31 | #include <utility> |
|---|
| 32 | #include <list> |
|---|
| 33 | |
|---|
| 34 | using std::list; |
|---|
| 35 | |
|---|
| 36 | class MainFrm; |
|---|
| 37 | class PointInfo; |
|---|
| 38 | |
|---|
| 39 | struct ColourTriple { |
|---|
| 40 | // RGB triple: values are from 0-255 inclusive for each component. |
|---|
| 41 | int r; |
|---|
| 42 | int g; |
|---|
| 43 | int b; |
|---|
| 44 | }; |
|---|
| 45 | |
|---|
| 46 | // Colours for drawing. |
|---|
| 47 | // These must be in the same order as the entries in COLOURS[] in gfxcore.cc. |
|---|
| 48 | enum AvenColour { |
|---|
| 49 | col_BLACK = 0, |
|---|
| 50 | col_GREY, |
|---|
| 51 | col_LIGHT_GREY, |
|---|
| 52 | col_LIGHT_GREY_2, |
|---|
| 53 | col_DARK_GREY, |
|---|
| 54 | col_WHITE, |
|---|
| 55 | col_TURQUOISE, |
|---|
| 56 | col_GREEN, |
|---|
| 57 | col_INDICATOR_1, |
|---|
| 58 | col_INDICATOR_2, |
|---|
| 59 | col_YELLOW, |
|---|
| 60 | col_RED, |
|---|
| 61 | col_LAST // must be the last entry here |
|---|
| 62 | }; |
|---|
| 63 | |
|---|
| 64 | class Point { |
|---|
| 65 | friend class GfxCore; |
|---|
| 66 | Double x, y, z; |
|---|
| 67 | public: |
|---|
| 68 | Point() {} |
|---|
| 69 | Point(Double x_, Double y_, Double z_) : x(x_), y(y_), z(z_) {} |
|---|
| 70 | }; |
|---|
| 71 | |
|---|
| 72 | class LabelInfo; |
|---|
| 73 | |
|---|
| 74 | extern const ColourTriple COLOURS[]; // defined in gfxcore.cc |
|---|
| 75 | |
|---|
| 76 | class GfxCore : public wxWindow { |
|---|
| 77 | struct params { |
|---|
| 78 | Quaternion rotation; |
|---|
| 79 | Double scale; |
|---|
| 80 | struct { |
|---|
| 81 | Double x; |
|---|
| 82 | Double y; |
|---|
| 83 | Double z; |
|---|
| 84 | } translation; |
|---|
| 85 | } m_Params; |
|---|
| 86 | |
|---|
| 87 | enum LockFlags { |
|---|
| 88 | lock_NONE = 0, |
|---|
| 89 | lock_X = 1, |
|---|
| 90 | lock_Y = 2, |
|---|
| 91 | lock_Z = 4, |
|---|
| 92 | lock_POINT = lock_X | lock_Y | lock_Z, |
|---|
| 93 | lock_XZ = lock_X | lock_Z, |
|---|
| 94 | lock_YZ = lock_Y | lock_Z, |
|---|
| 95 | lock_XY = lock_X | lock_Y |
|---|
| 96 | }; |
|---|
| 97 | |
|---|
| 98 | struct PlotData { |
|---|
| 99 | Point *vertices; |
|---|
| 100 | Point *surface_vertices; |
|---|
| 101 | int* num_segs; |
|---|
| 102 | int* surface_num_segs; |
|---|
| 103 | }; |
|---|
| 104 | |
|---|
| 105 | struct { |
|---|
| 106 | int offset_x; |
|---|
| 107 | int offset_y; |
|---|
| 108 | int width; |
|---|
| 109 | int drag_start_offset_x; |
|---|
| 110 | int drag_start_offset_y; |
|---|
| 111 | } m_ScaleBar; |
|---|
| 112 | |
|---|
| 113 | double m_MaxExtent; // twice the maximum of the {x,y,z}-extents, in survey coordinates. |
|---|
| 114 | char *m_LabelGrid; |
|---|
| 115 | bool m_RotationOK; |
|---|
| 116 | LockFlags m_Lock; |
|---|
| 117 | Matrix4 m_RotationMatrix; |
|---|
| 118 | bool m_DraggingLeft; |
|---|
| 119 | bool m_DraggingMiddle; |
|---|
| 120 | bool m_DraggingRight; |
|---|
| 121 | MainFrm* m_Parent; |
|---|
| 122 | wxPoint m_DragStart; |
|---|
| 123 | wxPoint m_DragRealStart; |
|---|
| 124 | wxPoint m_DragLast; |
|---|
| 125 | wxBitmap* m_OffscreenBitmap; |
|---|
| 126 | wxMemoryDC m_DrawDC; |
|---|
| 127 | bool m_DoneFirstShow; |
|---|
| 128 | bool m_RedrawOffscreen; |
|---|
| 129 | int* m_Polylines; |
|---|
| 130 | int* m_SurfacePolylines; |
|---|
| 131 | int m_Bands; |
|---|
| 132 | Double m_InitialScale; |
|---|
| 133 | Double m_TiltAngle; |
|---|
| 134 | Double m_PanAngle; |
|---|
| 135 | bool m_Rotating; |
|---|
| 136 | Double m_RotationStep; |
|---|
| 137 | int m_SwitchingTo; |
|---|
| 138 | bool m_ReverseControls; |
|---|
| 139 | bool m_Crosses; |
|---|
| 140 | bool m_Legs; |
|---|
| 141 | bool m_Names; |
|---|
| 142 | bool m_Scalebar; |
|---|
| 143 | wxFont m_Font; |
|---|
| 144 | bool m_Depthbar; |
|---|
| 145 | bool m_OverlappingNames; |
|---|
| 146 | bool m_Compass; |
|---|
| 147 | bool m_Clino; |
|---|
| 148 | int m_XSize; |
|---|
| 149 | int m_YSize; |
|---|
| 150 | int m_XCentre; |
|---|
| 151 | int m_YCentre; |
|---|
| 152 | PlotData* m_PlotData; |
|---|
| 153 | bool m_InitialisePending; |
|---|
| 154 | enum { drag_NONE, drag_MAIN, drag_COMPASS, drag_ELEV, drag_SCALE } m_LastDrag; |
|---|
| 155 | bool m_MouseOutsideCompass; |
|---|
| 156 | bool m_MouseOutsideElev; |
|---|
| 157 | bool m_UndergroundLegs; |
|---|
| 158 | bool m_SurfaceLegs; |
|---|
| 159 | bool m_Surface; |
|---|
| 160 | bool m_SurfaceDashed; |
|---|
| 161 | bool m_SurfaceDepth; |
|---|
| 162 | bool m_Entrances; |
|---|
| 163 | bool m_FixedPts; |
|---|
| 164 | bool m_ExportedPts; |
|---|
| 165 | bool m_Grid; |
|---|
| 166 | |
|---|
| 167 | list<LabelInfo*> *m_PointGrid; |
|---|
| 168 | bool m_HitTestGridValid; |
|---|
| 169 | |
|---|
| 170 | Point m_here, m_there; |
|---|
| 171 | |
|---|
| 172 | wxStopWatch timer; |
|---|
| 173 | long drawtime; |
|---|
| 174 | |
|---|
| 175 | bool clipping; |
|---|
| 176 | |
|---|
| 177 | wxPen* m_Pens; |
|---|
| 178 | wxBrush* m_Brushes; |
|---|
| 179 | |
|---|
| 180 | void SetColour(AvenColour col, bool background = false /* true => foreground */) { |
|---|
| 181 | assert(col >= (AvenColour) 0 && col < col_LAST); |
|---|
| 182 | if (background) { |
|---|
| 183 | assert(m_Brushes[col].Ok()); |
|---|
| 184 | m_DrawDC.SetBrush(m_Brushes[col]); |
|---|
| 185 | } |
|---|
| 186 | else { |
|---|
| 187 | assert(m_Pens[col].Ok()); |
|---|
| 188 | m_DrawDC.SetPen(m_Pens[col]); |
|---|
| 189 | } |
|---|
| 190 | } |
|---|
| 191 | |
|---|
| 192 | Double XToScreen(Double x, Double y, Double z) { |
|---|
| 193 | return Double(x * m_RotationMatrix.get(0, 0) + |
|---|
| 194 | y * m_RotationMatrix.get(0, 1) + |
|---|
| 195 | z * m_RotationMatrix.get(0, 2)); |
|---|
| 196 | } |
|---|
| 197 | |
|---|
| 198 | Double YToScreen(Double x, Double y, Double z) { |
|---|
| 199 | return Double(x * m_RotationMatrix.get(1, 0) + |
|---|
| 200 | y * m_RotationMatrix.get(1, 1) + |
|---|
| 201 | z * m_RotationMatrix.get(1, 2)); |
|---|
| 202 | } |
|---|
| 203 | |
|---|
| 204 | Double ZToScreen(Double x, Double y, Double z) { |
|---|
| 205 | return Double(x * m_RotationMatrix.get(2, 0) + |
|---|
| 206 | y * m_RotationMatrix.get(2, 1) + |
|---|
| 207 | z * m_RotationMatrix.get(2, 2)); |
|---|
| 208 | } |
|---|
| 209 | |
|---|
| 210 | Double GridXToScreen(Double x, Double y, Double z); |
|---|
| 211 | Double GridYToScreen(Double x, Double y, Double z); |
|---|
| 212 | Double GridXToScreen(const Point &p) { |
|---|
| 213 | return GridXToScreen(p.x, p.y, p.z); |
|---|
| 214 | } |
|---|
| 215 | Double GridYToScreen(const Point &p) { |
|---|
| 216 | return GridYToScreen(p.x, p.y, p.z); |
|---|
| 217 | } |
|---|
| 218 | |
|---|
| 219 | void CheckHitTestGrid(wxPoint& point, bool centre); |
|---|
| 220 | |
|---|
| 221 | wxCoord GetClinoOffset(); |
|---|
| 222 | wxPoint CompassPtToScreen(Double x, Double y, Double z); |
|---|
| 223 | void DrawTick(wxCoord cx, wxCoord cy, int angle_cw); |
|---|
| 224 | wxString FormatLength(Double, bool scalebar = true); |
|---|
| 225 | |
|---|
| 226 | void SetScale(Double scale); |
|---|
| 227 | void SetScaleInitial(Double scale); |
|---|
| 228 | void DrawBand(int num_polylines, const int *num_segs, const Point *vertices, |
|---|
| 229 | Double m_00, Double m_01, Double m_02, |
|---|
| 230 | Double m_20, Double m_21, Double m_22); |
|---|
| 231 | void RedrawOffscreen(); |
|---|
| 232 | void TryToFreeArrays(); |
|---|
| 233 | void FirstShow(); |
|---|
| 234 | |
|---|
| 235 | void DrawScalebar(); |
|---|
| 236 | void DrawDepthbar(); |
|---|
| 237 | void Draw2dIndicators(); |
|---|
| 238 | void DrawGrid(); |
|---|
| 239 | |
|---|
| 240 | wxPoint IndicatorCompassToScreenPan(int angle); |
|---|
| 241 | wxPoint IndicatorCompassToScreenElev(int angle); |
|---|
| 242 | |
|---|
| 243 | void HandleScaleRotate(bool, wxPoint); |
|---|
| 244 | void HandleTilt(wxPoint); |
|---|
| 245 | void HandleTranslate(wxPoint); |
|---|
| 246 | |
|---|
| 247 | void TranslateCave(int dx, int dy); |
|---|
| 248 | void TiltCave(Double tilt_angle); |
|---|
| 249 | void TurnCave(Double angle); |
|---|
| 250 | void TurnCaveTo(Double angle); |
|---|
| 251 | |
|---|
| 252 | void DrawNames(); |
|---|
| 253 | void NattyDrawNames(); |
|---|
| 254 | void SimpleDrawNames(); |
|---|
| 255 | |
|---|
| 256 | void Repaint(); |
|---|
| 257 | |
|---|
| 258 | void CreateHitTestGrid(); |
|---|
| 259 | |
|---|
| 260 | public: |
|---|
| 261 | bool m_Degrees; |
|---|
| 262 | bool m_Metric; |
|---|
| 263 | |
|---|
| 264 | GfxCore(MainFrm* parent, wxWindow* parent_window); |
|---|
| 265 | ~GfxCore(); |
|---|
| 266 | |
|---|
| 267 | void Initialise(); |
|---|
| 268 | void InitialiseOnNextResize() { m_InitialisePending = true; } |
|---|
| 269 | void InitialiseTerrain(); |
|---|
| 270 | |
|---|
| 271 | void ForceRefresh(); |
|---|
| 272 | |
|---|
| 273 | void RefreshLine(const Point &a, const Point &b, const Point &c); |
|---|
| 274 | |
|---|
| 275 | void SetHere(); |
|---|
| 276 | void SetHere(Double x, Double y, Double z); |
|---|
| 277 | void SetThere(); |
|---|
| 278 | void SetThere(Double x, Double y, Double z); |
|---|
| 279 | |
|---|
| 280 | void CentreOn(Double x, Double y, Double z); |
|---|
| 281 | |
|---|
| 282 | void OnDefaults(); |
|---|
| 283 | void OnPlan(); |
|---|
| 284 | void OnElevation(); |
|---|
| 285 | void OnDisplayOverlappingNames(); |
|---|
| 286 | void OnShowCrosses(); |
|---|
| 287 | void OnShowStationNames(); |
|---|
| 288 | void OnShowSurveyLegs(); |
|---|
| 289 | void OnShowSurface(); |
|---|
| 290 | void OnShowSurfaceDepth(); |
|---|
| 291 | void OnShowSurfaceDashed(); |
|---|
| 292 | void OnMoveEast(); |
|---|
| 293 | void OnMoveNorth(); |
|---|
| 294 | void OnMoveSouth(); |
|---|
| 295 | void OnMoveWest(); |
|---|
| 296 | void OnStartRotation(); |
|---|
| 297 | void OnToggleRotation(); |
|---|
| 298 | void OnStopRotation(); |
|---|
| 299 | void OnReverseControls(); |
|---|
| 300 | void OnSlowDown(bool accel = false); |
|---|
| 301 | void OnSpeedUp(bool accel = false); |
|---|
| 302 | void OnStepOnceAnticlockwise(bool accel = false); |
|---|
| 303 | void OnStepOnceClockwise(bool accel = false); |
|---|
| 304 | void OnHigherViewpoint(bool accel = false); |
|---|
| 305 | void OnLowerViewpoint(bool accel = false); |
|---|
| 306 | void OnShiftDisplayDown(bool accel = false); |
|---|
| 307 | void OnShiftDisplayLeft(bool accel = false); |
|---|
| 308 | void OnShiftDisplayRight(bool accel = false); |
|---|
| 309 | void OnShiftDisplayUp(bool accel = false); |
|---|
| 310 | void OnZoomIn(bool accel = false); |
|---|
| 311 | void OnZoomOut(bool accel = false); |
|---|
| 312 | void OnToggleScalebar(); |
|---|
| 313 | void OnToggleDepthbar(); |
|---|
| 314 | void OnViewCompass(); |
|---|
| 315 | void OnViewClino(); |
|---|
| 316 | void OnViewGrid(); |
|---|
| 317 | void OnReverseDirectionOfRotation(); |
|---|
| 318 | void OnShowEntrances(); |
|---|
| 319 | void OnShowFixedPts(); |
|---|
| 320 | void OnShowExportedPts(); |
|---|
| 321 | void OnCancelDistLine(); |
|---|
| 322 | |
|---|
| 323 | void OnPaint(wxPaintEvent&); |
|---|
| 324 | void OnSize(wxSizeEvent& event); |
|---|
| 325 | void OnIdle(wxIdleEvent& event); |
|---|
| 326 | |
|---|
| 327 | void OnMouseMove(wxMouseEvent& event); |
|---|
| 328 | void OnLeaveWindow(wxMouseEvent& event); |
|---|
| 329 | |
|---|
| 330 | void OnLButtonDown(wxMouseEvent& event); |
|---|
| 331 | void OnLButtonUp(wxMouseEvent& event); |
|---|
| 332 | void OnMButtonDown(wxMouseEvent& event); |
|---|
| 333 | void OnMButtonUp(wxMouseEvent& event); |
|---|
| 334 | void OnRButtonDown(wxMouseEvent& event); |
|---|
| 335 | void OnRButtonUp(wxMouseEvent& event); |
|---|
| 336 | bool Animate(); |
|---|
| 337 | |
|---|
| 338 | void OnKeyPress(wxKeyEvent &e); |
|---|
| 339 | |
|---|
| 340 | void OnDisplayOverlappingNamesUpdate(wxUpdateUIEvent&); |
|---|
| 341 | void OnShowCrossesUpdate(wxUpdateUIEvent&); |
|---|
| 342 | void OnShowStationNamesUpdate(wxUpdateUIEvent&); |
|---|
| 343 | void OnShowSurveyLegsUpdate(wxUpdateUIEvent&); |
|---|
| 344 | void OnShowSurfaceUpdate(wxUpdateUIEvent&); |
|---|
| 345 | void OnShowSurfaceDepthUpdate(wxUpdateUIEvent&); |
|---|
| 346 | void OnShowSurfaceDashedUpdate(wxUpdateUIEvent&); |
|---|
| 347 | void OnMoveEastUpdate(wxUpdateUIEvent&); |
|---|
| 348 | void OnMoveNorthUpdate(wxUpdateUIEvent&); |
|---|
| 349 | void OnMoveSouthUpdate(wxUpdateUIEvent&); |
|---|
| 350 | void OnMoveWestUpdate(wxUpdateUIEvent&); |
|---|
| 351 | void OnStartRotationUpdate(wxUpdateUIEvent&); |
|---|
| 352 | void OnToggleRotationUpdate(wxUpdateUIEvent&); |
|---|
| 353 | void OnStopRotationUpdate(wxUpdateUIEvent&); |
|---|
| 354 | void OnReverseControlsUpdate(wxUpdateUIEvent&); |
|---|
| 355 | void OnReverseDirectionOfRotationUpdate(wxUpdateUIEvent&); |
|---|
| 356 | void OnSlowDownUpdate(wxUpdateUIEvent&); |
|---|
| 357 | void OnSpeedUpUpdate(wxUpdateUIEvent&); |
|---|
| 358 | void OnStepOnceAnticlockwiseUpdate(wxUpdateUIEvent&); |
|---|
| 359 | void OnStepOnceClockwiseUpdate(wxUpdateUIEvent&); |
|---|
| 360 | void OnDefaultsUpdate(wxUpdateUIEvent&); |
|---|
| 361 | void OnElevationUpdate(wxUpdateUIEvent&); |
|---|
| 362 | void OnHigherViewpointUpdate(wxUpdateUIEvent&); |
|---|
| 363 | void OnLowerViewpointUpdate(wxUpdateUIEvent&); |
|---|
| 364 | void OnPlanUpdate(wxUpdateUIEvent&); |
|---|
| 365 | void OnShiftDisplayDownUpdate(wxUpdateUIEvent&); |
|---|
| 366 | void OnShiftDisplayLeftUpdate(wxUpdateUIEvent&); |
|---|
| 367 | void OnShiftDisplayRightUpdate(wxUpdateUIEvent&); |
|---|
| 368 | void OnShiftDisplayUpUpdate(wxUpdateUIEvent&); |
|---|
| 369 | void OnZoomInUpdate(wxUpdateUIEvent&); |
|---|
| 370 | void OnZoomOutUpdate(wxUpdateUIEvent&); |
|---|
| 371 | void OnToggleScalebarUpdate(wxUpdateUIEvent&); |
|---|
| 372 | void OnToggleDepthbarUpdate(wxUpdateUIEvent&); |
|---|
| 373 | void OnViewCompassUpdate(wxUpdateUIEvent&); |
|---|
| 374 | void OnViewClinoUpdate(wxUpdateUIEvent&); |
|---|
| 375 | void OnViewGridUpdate(wxUpdateUIEvent&); |
|---|
| 376 | void OnShowEntrancesUpdate(wxUpdateUIEvent&); |
|---|
| 377 | void OnShowExportedPtsUpdate(wxUpdateUIEvent&); |
|---|
| 378 | void OnShowFixedPtsUpdate(wxUpdateUIEvent&); |
|---|
| 379 | void OnIndicatorsUpdate(wxUpdateUIEvent&); |
|---|
| 380 | void OnCancelDistLineUpdate(wxUpdateUIEvent&); |
|---|
| 381 | |
|---|
| 382 | void OnToggleMetric(); |
|---|
| 383 | void OnToggleMetricUpdate(wxUpdateUIEvent& cmd); |
|---|
| 384 | |
|---|
| 385 | void OnToggleDegrees(); |
|---|
| 386 | void OnToggleDegreesUpdate(wxUpdateUIEvent& cmd); |
|---|
| 387 | |
|---|
| 388 | void OnPrint(const wxString &filename, const wxString &title, |
|---|
| 389 | const wxString &datestamp); |
|---|
| 390 | bool OnExport(const wxString &filename, const wxString &title); |
|---|
| 391 | |
|---|
| 392 | private: |
|---|
| 393 | DECLARE_EVENT_TABLE() |
|---|
| 394 | }; |
|---|
| 395 | |
|---|
| 396 | #endif |
|---|