source: git/src/gfxcore.h@ fc43dda

RELEASE/1.2 debug-ci debug-ci-sanitisers faster-cavernlog log-select main stereo-2025 walls-data walls-data-hanging-as-warning warn-only-for-hanging-survey
Last change on this file since fc43dda was fc43dda, checked in by Olly Betts <olly@…>, 7 years ago

Allow colouring by horizontal or vertical error

  • Property mode set to 100644
File size: 18.5 KB
Line 
1//
2// gfxcore.h
3//
4// Core drawing code for Aven.
5//
6// Copyright (C) 2000-2001,2002,2005 Mark R. Shinwell.
7// Copyright (C) 2001-2004,2005,2006,2007,2010,2011,2012,2013,2014,2015,2016,2017,2018 Olly Betts
8// Copyright (C) 2005 Martin Green
9//
10// This program is free software; you can redistribute it and/or modify
11// it under the terms of the GNU General Public License as published by
12// the Free Software Foundation; either version 2 of the License, or
13// (at your option) any later version.
14//
15// This program is distributed in the hope that it will be useful,
16// but WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with this program; if not, write to the Free Software
22// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23//
24
25#ifndef gfxcore_h
26#define gfxcore_h
27
28#include <float.h>
29#include <limits.h>
30#include <time.h>
31
32#include "img_hosted.h"
33
34#include "guicontrol.h"
35#include "labelinfo.h"
36#include "vector3.h"
37#include "wx.h"
38#include "gla.h"
39
40#include <list>
41#include <utility>
42#include <vector>
43
44using namespace std;
45
46class MainFrm;
47class traverse;
48
49class XSect;
50class PointInfo;
51class MovieMaker;
52
53class PresentationMark : public Point {
54 public:
55 Double angle, tilt_angle;
56 Double scale;
57 Double time;
58 PresentationMark() : Point(), angle(0), tilt_angle(0), scale(0), time(0)
59 { }
60 PresentationMark(const Vector3 & v, Double angle_, Double tilt_angle_,
61 Double scale_, Double time_ = 0)
62 : Point(v), angle(angle_), tilt_angle(tilt_angle_), scale(scale_),
63 time(time_)
64 { }
65 bool is_valid() const { return scale > 0; }
66};
67
68struct ZoomBox {
69 public:
70 int x1, y1, x2, y2;
71
72 ZoomBox()
73 : x1(INT_MAX) { }
74
75 bool active() const { return x1 != INT_MAX; }
76
77 void set(const wxPoint & p1, const wxPoint & p2) {
78 x1 = p1.x;
79 y1 = p1.y;
80 x2 = p2.x;
81 y2 = p2.y;
82 }
83
84 void unset() {
85 x1 = INT_MAX;
86 }
87};
88
89enum {
90 COLOUR_BY_NONE,
91 COLOUR_BY_DEPTH,
92 COLOUR_BY_DATE,
93 COLOUR_BY_ERROR,
94 COLOUR_BY_H_ERROR,
95 COLOUR_BY_V_ERROR,
96 COLOUR_BY_GRADIENT,
97 COLOUR_BY_LENGTH,
98 COLOUR_BY_SURVEY,
99 COLOUR_BY_LIMIT_ // Leave this last.
100};
101
102enum {
103 UPDATE_NONE,
104 UPDATE_BLOBS,
105 UPDATE_BLOBS_AND_CROSSES
106};
107
108enum {
109 SHOW_HIDE,
110 SHOW_DASHED,
111 SHOW_FADED,
112 SHOW_NORMAL,
113};
114
115struct Split {
116 Vector3 vec;
117 glaCoord tx, ty;
118
119 Split(const Vector3& vec_, glaCoord tx_, glaCoord ty_)
120 : vec(vec_), tx(tx_), ty(ty_) { }
121};
122
123// It's pointless to redraw the screen as often as we can on a fast machine,
124// since the display hardware will only update so many times per second.
125// This is the maximum framerate we'll redraw at.
126const int MAX_FRAMERATE = 50;
127
128class GfxCore : public GLACanvas {
129 Double m_Scale;
130 Double initial_scale;
131 int m_ScaleBarWidth;
132
133 typedef enum {
134 LIST_COMPASS,
135 LIST_CLINO,
136 LIST_CLINO_BACK,
137 LIST_SCALE_BAR,
138 LIST_DEPTH_KEY,
139 LIST_DATE_KEY,
140 LIST_ERROR_KEY,
141 LIST_GRADIENT_KEY,
142 LIST_LENGTH_KEY,
143 LIST_UNDERGROUND_LEGS,
144 LIST_TUBES,
145 LIST_SURFACE_LEGS,
146 LIST_BLOBS,
147 LIST_CROSSES,
148 LIST_GRID,
149 LIST_SHADOW,
150 LIST_TERRAIN,
151 LIST_LIMIT_ // Leave this last.
152 } drawing_list;
153
154 static const int NUM_COLOUR_BANDS = 13;
155
156 void SetPanBase() {
157 base_pan = m_PanAngle;
158 base_pan_time = timer.Time() - (1000 / MAX_FRAMERATE);
159 }
160
161 void SetTiltBase() {
162 base_tilt = m_TiltAngle;
163 base_tilt_time = timer.Time() - (1000 / MAX_FRAMERATE);
164 }
165
166 int GetCompassWidth() const;
167 int GetClinoWidth() const;
168
169public:
170 typedef enum {
171 CURSOR_DEFAULT,
172 CURSOR_POINTING_HAND,
173 CURSOR_DRAGGING_HAND,
174 CURSOR_HORIZONTAL_RESIZE,
175 CURSOR_ROTATE_HORIZONTALLY,
176 CURSOR_ROTATE_VERTICALLY,
177 CURSOR_ROTATE_EITHER_WAY,
178 CURSOR_ZOOM,
179 CURSOR_ZOOM_ROTATE
180 } cursor;
181
182private:
183 GUIControl* m_Control;
184 char* m_LabelGrid;
185 MainFrm* m_Parent;
186 bool m_DoneFirstShow;
187 Double m_TiltAngle;
188 Double m_PanAngle;
189 bool m_Rotating;
190 Double m_RotationStep;
191 int m_SwitchingTo;
192 bool m_Crosses;
193 bool m_Legs;
194 int m_Splays;
195 int m_Dupes;
196 bool m_Names;
197 bool m_Scalebar;
198 bool m_ColourKey;
199 bool m_OverlappingNames;
200 bool m_Compass;
201 bool m_Clino;
202 bool m_Tubes;
203 int m_ColourBy;
204 int error_type;
205
206 bool m_HaveData;
207 bool m_HaveTerrain;
208 bool m_MouseOutsideCompass;
209 bool m_MouseOutsideElev;
210 bool m_Surface;
211 bool m_Entrances;
212 bool m_FixedPts;
213 bool m_ExportedPts;
214 bool m_Grid;
215 bool m_BoundingBox;
216 bool m_Terrain;
217
218 bool m_Degrees;
219 bool m_Metric;
220 bool m_Percent;
221
222 bool m_HitTestDebug;
223 bool m_RenderStats;
224
225 list<LabelInfo*> *m_PointGrid;
226 bool m_HitTestGridValid;
227
228 LabelInfo temp_here;
229 const LabelInfo * m_here;
230 const LabelInfo * m_there;
231 wxString highlighted_survey;
232
233 wxStopWatch timer;
234 long base_tilt_time;
235 long base_pan_time;
236 Double base_tilt;
237 Double base_pan;
238
239 GLAPen m_Pens[NUM_COLOUR_BANDS + 1];
240
241#define PLAYING 1
242 int presentation_mode; // for now, 0 => off, PLAYING => continuous play
243 bool pres_reverse;
244 double pres_speed;
245 PresentationMark next_mark;
246 double next_mark_time;
247 double this_mark_total;
248
249 MovieMaker * movie;
250
251 cursor current_cursor;
252
253 int sqrd_measure_threshold;
254
255 // The legends for each entry in the colour key.
256 wxString key_legends[NUM_COLOUR_BANDS];
257
258 wxPoint key_lowerleft[COLOUR_BY_LIMIT_];
259
260 ZoomBox zoombox;
261
262 // Copied from parent, so we can adjust view when reloading the same
263 // file with the view restricted.
264 Vector3 offsets;
265
266 // DEM:
267 unsigned short * dem;
268 unsigned long dem_width, dem_height;
269 double o_x, o_y, step_x, step_y;
270 long nodata_value;
271 bool bigendian;
272 long last_time;
273 size_t n_tris;
274
275 void PlaceVertexWithColour(const Vector3 &v, Double factor = 1.0);
276 void PlaceVertexWithColour(const Vector3 & v,
277 glaTexCoord tex_x, glaTexCoord tex_y,
278 Double factor);
279 void SetDepthColour(Double z, Double factor);
280 void PlaceVertexWithDepthColour(const Vector3 & v, Double factor = 1.0);
281 void PlaceVertexWithDepthColour(const Vector3 & v,
282 glaTexCoord tex_x, glaTexCoord tex_y,
283 Double factor);
284
285 void SetColourFrom01(double how_far, Double factor);
286
287 void SetColourFromDate(int date, Double factor);
288 void SetColourFromError(double E, Double factor);
289 void SetColourFromGradient(double angle, Double factor);
290 void SetColourFromLength(double len, Double factor);
291 void SetColourFromSurvey(const wxString& survey);
292 void SetColourFromSurveyStation(const wxString& survey, Double factor);
293
294 int GetClinoOffset() const;
295 void DrawTick(int angle_cw);
296 void DrawArrow(gla_colour col1, gla_colour col2);
297
298 void SkinPassage(vector<XSect> & centreline);
299
300 virtual void GenerateList(unsigned int l);
301 void GenerateDisplayList(bool surface);
302 void GenerateDisplayListTubes();
303 void DrawTerrainTriangle(const Vector3 & a, const Vector3 & b, const Vector3 & c);
304 void DrawTerrain();
305 void GenerateDisplayListShadow();
306 void GenerateBlobsDisplayList();
307
308 void DrawIndicators();
309
310 void TryToFreeArrays();
311 void FirstShow();
312
313 void DrawScaleBar();
314 void DrawColourKey(int num_bands, const wxString & other, const wxString & units);
315 void DrawDepthKey();
316 void DrawDateKey();
317 void DrawErrorKey();
318 void DrawGradientKey();
319 void DrawLengthKey();
320 void DrawCompass();
321 void DrawClino();
322 void DrawClinoBack();
323 void Draw2dIndicators();
324 void DrawGrid();
325
326 void NattyDrawNames();
327 void SimpleDrawNames();
328
329 void DefaultParameters();
330
331 void Repaint();
332
333 void CreateHitTestGrid();
334
335 int GetCompassXPosition() const;
336 int GetClinoXPosition() const;
337 int GetIndicatorYPosition() const;
338 int GetIndicatorRadius() const;
339
340 void ToggleFlag(bool* flag, int update = UPDATE_NONE);
341
342 const GLAPen& GetPen(int band) const {
343 assert(band >= 0 && band < NUM_COLOUR_BANDS);
344 return m_Pens[band];
345 }
346
347 const GLAPen& GetSurfacePen() const { return m_Pens[NUM_COLOUR_BANDS]; }
348
349 int GetNumColourBands() const { return NUM_COLOUR_BANDS; }
350
351 void DrawShadowedBoundingBox();
352 void DrawBoundingBox();
353
354public:
355 GfxCore(MainFrm* parent, wxWindow* parent_window, GUIControl* control);
356 ~GfxCore();
357
358 void Initialise(bool same_file);
359
360 void UpdateBlobs();
361 void ForceRefresh();
362
363 void RefreshLine(const Point* a, const Point* b, const Point* c);
364
365 void SetHereSurvey(const wxString& survey) {
366 if (survey != highlighted_survey) {
367 highlighted_survey = survey;
368 ForceRefresh();
369 }
370 }
371
372 void HighlightSurvey();
373
374 void ZoomToSurvey(const wxString& survey);
375
376 void SetHereFromTree(const LabelInfo * p);
377
378 void SetHere(const LabelInfo * p = NULL);
379 void SetThere(const LabelInfo * p = NULL);
380
381 const LabelInfo* GetThere() const { return m_there; }
382
383 void CentreOn(const Point &p);
384
385 void TranslateCave(int dx, int dy);
386 void TiltCave(Double tilt_angle);
387 void TurnCave(Double angle);
388 void TurnCaveTo(Double angle);
389
390 void OnPaint(wxPaintEvent&);
391 void OnSize(wxSizeEvent& event);
392 void OnIdle(wxIdleEvent& event);
393
394 void OnMouseMove(wxMouseEvent& event) { m_Control->OnMouseMove(event); }
395 void OnLeaveWindow(wxMouseEvent& event);
396
397 void OnLButtonDown(wxMouseEvent& event) { SetFocus(); m_Control->OnLButtonDown(event); }
398 void OnLButtonUp(wxMouseEvent& event) { m_Control->OnLButtonUp(event); }
399 void OnMButtonDown(wxMouseEvent& event) { SetFocus(); m_Control->OnMButtonDown(event); }
400 void OnMButtonUp(wxMouseEvent& event) { m_Control->OnMButtonUp(event); }
401 void OnRButtonDown(wxMouseEvent& event) { SetFocus(); m_Control->OnRButtonDown(event); }
402 void OnRButtonUp(wxMouseEvent& event) { m_Control->OnRButtonUp(event); }
403 void OnMouseWheel(wxMouseEvent& event) { SetFocus(); m_Control->OnMouseWheel(event); }
404 void OnKeyPress(wxKeyEvent &event) { m_Control->OnKeyPress(event); }
405
406 void Animate();
407 bool Animating() const {
408 return m_Rotating || m_SwitchingTo || presentation_mode != 0;
409 }
410
411 void ClearCoords();
412 void SetCoords(wxPoint);
413
414 // Determine whether the compass is currently shown.
415 bool ShowingCompass() const { return m_Compass; }
416 // Determine whether the clino is currently shown.
417 bool ShowingClino() const { return m_Clino; }
418
419 bool PointWithinCompass(wxPoint point) const;
420 bool PointWithinClino(wxPoint point) const;
421 bool PointWithinScaleBar(wxPoint point) const;
422 bool PointWithinColourKey(wxPoint point) const;
423
424 void SetCompassFromPoint(wxPoint point);
425 void SetClinoFromPoint(wxPoint point);
426 void SetScaleBarFromOffset(wxCoord dx);
427
428 void RedrawIndicators();
429
430 void StartRotation();
431 void ToggleRotation();
432 void StopRotation();
433 bool IsExtendedElevation() const;
434 void ReverseRotation();
435 void RotateSlower(bool accel);
436 void RotateFaster(bool accel);
437
438 void SwitchToElevation();
439 void SwitchToPlan();
440
441 void SetViewTo(Double xmin, Double xmax, Double ymin, Double ymax, Double zmin, Double zmax);
442
443 double GetCompassValue() const { return m_PanAngle; }
444 bool ShowingPlan() const;
445 bool ShowingElevation() const;
446 bool ShowingMeasuringLine() const;
447 bool HereIsReal() const { return m_here && m_here != &temp_here; }
448
449 bool CanRaiseViewpoint() const;
450 bool CanLowerViewpoint() const;
451
452 bool IsRotating() const { return m_Rotating; }
453 bool HasData() const { return m_DoneFirstShow && m_HaveData; }
454 bool HasTerrain() const { return m_DoneFirstShow && m_HaveTerrain; }
455 bool HasDepth() const;
456 bool HasErrorInformation() const;
457 bool HasDateInformation() const;
458
459 double GetScale() const { return m_Scale; }
460 void SetScale(Double scale);
461
462 bool ShowingStationNames() const { return m_Names; }
463 bool ShowingOverlappingNames() const { return m_OverlappingNames; }
464 bool ShowingCrosses() const { return m_Crosses; }
465 bool ShowingGrid() const { return m_Grid; }
466
467 int ColouringBy() const { return m_ColourBy; }
468
469 bool HasUndergroundLegs() const;
470 bool HasSplays() const;
471 bool HasDupes() const;
472 bool HasSurfaceLegs() const;
473 bool HasTubes() const;
474
475 bool ShowingUndergroundLegs() const { return m_Legs; }
476 int ShowingSplaysMode() const { return m_Splays; }
477 int ShowingDupesMode() const { return m_Dupes; }
478 bool ShowingSurfaceLegs() const { return m_Surface; }
479
480 bool ShowingColourKey() const { return m_ColourKey; }
481 bool ShowingScaleBar() const { return m_Scalebar; }
482
483 bool ShowingEntrances() const { return m_Entrances; }
484 bool ShowingFixedPts() const { return m_FixedPts; }
485 bool ShowingExportedPts() const { return m_ExportedPts; }
486
487 int GetNumEntrances() const;
488 int GetNumFixedPts() const;
489 int GetNumExportedPts() const;
490
491 void ToggleUndergroundLegs() {
492 ToggleFlag(&m_Legs, UPDATE_BLOBS_AND_CROSSES);
493 }
494 void SetSplaysMode(int mode) {
495 m_Splays = mode;
496 UpdateBlobs();
497 InvalidateList(LIST_SURFACE_LEGS);
498 InvalidateList(LIST_UNDERGROUND_LEGS);
499 InvalidateList(LIST_CROSSES);
500 m_HitTestGridValid = false;
501 ForceRefresh();
502 }
503 void SetDupesMode(int mode) {
504 m_Dupes = mode;
505 UpdateBlobs();
506 InvalidateList(LIST_SURFACE_LEGS);
507 InvalidateList(LIST_UNDERGROUND_LEGS);
508 ForceRefresh();
509 }
510 void ToggleSurfaceLegs() {
511 ToggleFlag(&m_Surface, UPDATE_BLOBS_AND_CROSSES);
512 }
513 void ToggleCompass() {
514 ToggleFlag(&m_Compass);
515 InvalidateList(LIST_SCALE_BAR);
516 }
517 void ToggleClino() {
518 ToggleFlag(&m_Clino);
519 InvalidateList(LIST_SCALE_BAR);
520 }
521 void ToggleScaleBar() { ToggleFlag(&m_Scalebar); }
522 void ToggleEntrances() { ToggleFlag(&m_Entrances, UPDATE_BLOBS); }
523 void ToggleFixedPts() { ToggleFlag(&m_FixedPts, UPDATE_BLOBS); }
524 void ToggleExportedPts() { ToggleFlag(&m_ExportedPts, UPDATE_BLOBS); }
525 void ToggleGrid() { ToggleFlag(&m_Grid); }
526 void ToggleCrosses() { ToggleFlag(&m_Crosses); }
527 void ToggleStationNames() { ToggleFlag(&m_Names); }
528 void ToggleOverlappingNames() { ToggleFlag(&m_OverlappingNames); }
529 void ToggleColourKey() { ToggleFlag(&m_ColourKey); }
530 void ToggleMetric() {
531 ToggleFlag(&m_Metric);
532 InvalidateList(LIST_DEPTH_KEY);
533 InvalidateList(LIST_LENGTH_KEY);
534 InvalidateList(LIST_SCALE_BAR);
535 }
536 void ToggleHitTestDebug() {
537 ToggleFlag(&m_HitTestDebug);
538 }
539 void ToggleRenderStats() {
540 ToggleFlag(&m_RenderStats);
541 }
542 void ToggleDegrees() {
543 ToggleFlag(&m_Degrees);
544 InvalidateList(LIST_GRADIENT_KEY);
545 }
546 void TogglePercent() { ToggleFlag(&m_Percent); }
547 void ToggleTubes() { ToggleFlag(&m_Tubes); }
548 void TogglePerspective() { GLACanvas::TogglePerspective(); ForceRefresh(); }
549 void ToggleSmoothShading();
550 bool DisplayingBoundingBox() const { return m_BoundingBox; }
551 void ToggleBoundingBox() { ToggleFlag(&m_BoundingBox); }
552 bool DisplayingTerrain() const { return m_Terrain; }
553 void ToggleTerrain();
554 void ToggleFatFinger();
555 void ToggleTextured() {
556 GLACanvas::ToggleTextured();
557 ForceRefresh();
558 }
559
560 bool GetMetric() const { return m_Metric; }
561 bool GetDegrees() const { return m_Degrees; }
562 bool GetPercent() const { return m_Percent; }
563 bool GetTubes() const { return m_Tubes; }
564
565 bool CheckHitTestGrid(const wxPoint& point, bool centre);
566
567 void ClearTreeSelection();
568
569 void Defaults();
570
571 void FullScreenMode();
572
573 bool IsFullScreen() const;
574
575 bool FullScreenModeShowingMenus() const;
576
577 void FullScreenModeShowMenus(bool show);
578
579 void DragFinished();
580
581 void SplitLineAcrossBands(int band, int band2,
582 const Vector3 &p, const Vector3 &q,
583 Double factor = 1.0);
584 void SplitPolyAcrossBands(vector<vector<Split>>& splits,
585 int band, int band2,
586 const Vector3 &p, const Vector3 &q,
587 glaTexCoord ptx, glaTexCoord pty,
588 glaTexCoord w, glaTexCoord h);
589 int GetDepthColour(Double z) const;
590 Double GetDepthBoundaryBetweenBands(int a, int b) const;
591 void AddPolyline(const traverse & centreline);
592 void AddPolylineDepth(const traverse & centreline);
593 void AddPolylineDate(const traverse & centreline);
594 void AddPolylineError(const traverse & centreline);
595 void AddPolylineGradient(const traverse & centreline);
596 void AddPolylineLength(const traverse & centreline);
597 void AddPolylineSurvey(const traverse & centreline);
598 void AddQuadrilateral(const Vector3 &a, const Vector3 &b,
599 const Vector3 &c, const Vector3 &d);
600 void AddPolylineShadow(const traverse & centreline);
601 void AddQuadrilateralDepth(const Vector3 &a, const Vector3 &b,
602 const Vector3 &c, const Vector3 &d);
603 void AddQuadrilateralDate(const Vector3 &a, const Vector3 &b,
604 const Vector3 &c, const Vector3 &d);
605 void AddQuadrilateralError(const Vector3 &a, const Vector3 &b,
606 const Vector3 &c, const Vector3 &d);
607 void AddQuadrilateralGradient(const Vector3 &a, const Vector3 &b,
608 const Vector3 &c, const Vector3 &d);
609 void AddQuadrilateralLength(const Vector3 &a, const Vector3 &b,
610 const Vector3 &c, const Vector3 &d);
611 void AddQuadrilateralSurvey(const Vector3 &a, const Vector3 &b,
612 const Vector3 &c, const Vector3 &d);
613 void MoveViewer(double forward, double up, double right);
614
615 void (GfxCore::* AddQuad)(const Vector3 &a, const Vector3 &b,
616 const Vector3 &c, const Vector3 &d);
617 void (GfxCore::* AddPoly)(const traverse & centreline);
618
619 PresentationMark GetView() const;
620 void SetView(const PresentationMark & p);
621 void PlayPres(double speed, bool change_speed = true);
622 int GetPresentationMode() const { return presentation_mode; }
623 double GetPresentationSpeed() const { return presentation_mode ? pres_speed : 0; }
624
625 void SetColourBy(int colour_by);
626 bool ExportMovie(const wxString & fnm);
627 void OnPrint(const wxString &filename, const wxString &title,
628 const wxString &datestamp,
629 bool close_after_print = false);
630 void OnExport(const wxString &filename, const wxString &title,
631 const wxString &datestamp);
632 void UpdateCursor(GfxCore::cursor new_cursor);
633 bool MeasuringLineActive() const;
634
635 bool HandleRClick(wxPoint point);
636
637 void InvalidateAllLists() {
638 for (int i = 0; i < LIST_LIMIT_; ++i) {
639 InvalidateList(i);
640 }
641 }
642
643 void SetZoomBox(wxPoint p1, wxPoint p2, bool centred, bool aspect);
644
645 void UnsetZoomBox() {
646 if (!zoombox.active()) return;
647 zoombox.unset();
648 ForceRefresh();
649 }
650
651 void ZoomBoxGo();
652
653 void parse_hgt_filename(const wxString & lc_name);
654 size_t parse_hdr(wxInputStream & is, unsigned long & skipbytes);
655 bool read_bil(wxInputStream & is, size_t size, unsigned long skipbytes);
656 bool LoadDEM(const wxString & file);
657
658private:
659 DECLARE_EVENT_TABLE()
660};
661
662#endif
Note: See TracBrowser for help on using the repository browser.