From 6f63d3f94a8a361de5e7f4d28e3a1a5cf1e8ba1f Mon Sep 17 00:00:00 2001 From: James Hogan Date: Tue, 10 Mar 2009 13:51:23 +0000 Subject: [PATCH] Cross sectioning --- geo/tcChannel.cpp | 9 +++ geo/tcChannel.h | 10 ++++ tcViewportWidget.cpp | 151 ++++++++++++++++++++++++++++++++++++++++++++++++--- tcViewportWidget.h | 12 ++++ 4 files changed, 174 insertions(+), 8 deletions(-) diff --git a/geo/tcChannel.cpp b/geo/tcChannel.cpp index a2c3cca..77b203b 100644 --- a/geo/tcChannel.cpp +++ b/geo/tcChannel.cpp @@ -45,6 +45,7 @@ tcChannel::tcChannel(const QString& name, const QString& description) , m_description(description) , m_radianceOffset(0.0f) , m_radianceGain(1.0f) +, m_crossSectioned(false) { } @@ -100,6 +101,14 @@ void tcChannel::setRadianceTransform(float offset, float gain) m_radianceGain = gain; } +/// New cross section selected. +void tcChannel::newCrossSection(const tcGeo& p1, const tcGeo& p2) +{ + m_crossSectioned = true; + m_crossSection[0] = p1; + m_crossSection[1] = p1; +} + /* * Dependencies */ diff --git a/geo/tcChannel.h b/geo/tcChannel.h index be424b7..36f9ee7 100644 --- a/geo/tcChannel.h +++ b/geo/tcChannel.h @@ -26,6 +26,7 @@ */ #include "tcPixelData.h" +#include "tcGeo.h" #include #include @@ -78,6 +79,9 @@ class tcChannel : public QObject /// Set radiance offset and gain. void setRadianceTransform(float offset, float gain); + /// New cross section selected. + void newCrossSection(const tcGeo& p1, const tcGeo& p2); + /* * Dependencies */ @@ -196,6 +200,12 @@ class tcChannel : public QObject /// Radiance scaling information. float m_radianceOffset, m_radianceGain; + /// Whether cross sectioned. + bool m_crossSectioned; + + /// Current cross section. + tcGeo m_crossSection[2]; + /* * Static variables */ diff --git a/tcViewportWidget.cpp b/tcViewportWidget.cpp index 986646c..81ff984 100644 --- a/tcViewportWidget.cpp +++ b/tcViewportWidget.cpp @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include #include @@ -51,7 +53,9 @@ tcViewportWidget::tcViewportWidget(QWidget* parent) , m_mouseIntersecting(false) , m_mouseCoord() , m_mouseSlicing(false) +, m_mouseCrossing(false) , m_sliced(false) +, m_crossSectioned(false) , m_texturePointObject(0) , m_texturePointMember(0) { @@ -219,6 +223,25 @@ void tcViewportWidget::setSlice(const tcGeo& sw, const tcGeo& ne) updateGL(); } +/// Set cross section. +void tcViewportWidget::setCrossSection(const tcGeo& p1, const tcGeo& p2) +{ + m_crossSectioned = true; + m_crossSection[0] = p1; + m_crossSection[1] = p2; + // Let all channels know of changes + QList imagery = m_globe->imagery(); + foreach (tcGeoImageData* image, imagery) + { + for (int i = 0; i < image->channelManager()->numChannels(); ++i) + { + image->channelManager()->channel(i)->newCrossSection(p1, p2); + } + } + updateGL(); +} + + /* * General rendering slots */ @@ -416,14 +439,10 @@ void tcViewportWidget::paintGL() m_observer->setupModelView(); - if (m_sliced) - { - m_globe->render(m_observer, m_adaptiveQuality, m_slice); - } - else - { - m_globe->render(m_observer); - } + m_globe->render(m_observer, + !m_sliced || m_adaptiveQuality, + (m_sliced ? m_slice : 0) + ); float meanRadius = m_globe->meanRadius(); @@ -528,6 +547,98 @@ void tcViewportWidget::paintGL() glEnd(); glEnable(GL_CULL_FACE); } + // Draw the cross section area + for (int i = 0; i < 2; ++i) + { + tcGeo coord; + tcGeo ending; + float colour[4] = {1.0f, 0.5f, 1.0f, 1.0f}; + if (0 == i && m_mouseCrossing && m_mouseIntersecting) + { + coord = m_mouseCoord; + ending = m_mouseStartCoord; + } + else if (1 == i && m_crossSectioned) + { + coord = m_crossSection[0]; + ending = m_crossSection[1]; + colour[0] = 0.0f; + colour[3] = 0.5f; + } + else + { + continue; + } + + tcGeo delta = ending - coord; + int nseg = 2 + fabs(delta.angle())*100*meanRadius / m_observer->range(); + double dlon = delta.lon() / (nseg-1); + double dlat = delta.lat() / (nseg-1); + + glDisable(GL_CULL_FACE); + // Lower bit + tcGeo tmp = coord; + glBegin(GL_TRIANGLE_STRIP); + for (int i = 0; i < nseg; ++i) + { + float radius = m_globe->radiusAt(tmp); + maths::Vector<3,double> coordVec = tmp; + glColor4fv(colour); + glVertex3(coordVec*radius); + glColor4f(1.0f, 1.0f, 1.0f, 0.5f); + glVertex3(coordVec*(radius + m_observer->range()*0.1)); + + tmp.setLon(tmp.lon() + dlon); + tmp.setLat(tmp.lat() + dlat); + } + glEnd(); + // Upper bit + tmp = coord; + glBegin(GL_TRIANGLE_STRIP); + glColor4f(1.0f, 1.0f, 1.0f, 0.5f); + for (int i = 0; i < nseg; ++i) + { + float radius = m_globe->radiusAt(tmp); + maths::Vector<3,double> coordVec = tmp; + glVertex3(coordVec*(radius + m_observer->range()*0.1)); + glVertex3(coordVec*(radius + m_observer->range()*0.6)); + + tmp.setLon(tmp.lon() + dlon); + tmp.setLat(tmp.lat() + dlat); + } + glEnd(); + glDisable(GL_DEPTH_TEST); + glEnable(GL_LINE_SMOOTH); + glLineWidth(2); + tcSrtmModel* model = m_globe->dem(); + for (int dem = 0; dem < 2; ++dem) + { + tmp = coord; + glBegin(GL_LINE_STRIP); + for (int i = 0; i < nseg; ++i) + { + bool accurate; + float radius = m_globe->meanRadius() + model[dem].altitudeAt(tmp, true, &accurate); + maths::Vector<3,double> coordVec = tmp; + if (accurate) + { + glColor4f(0.0f, 0.5f*dem, 0.5f*(1.0f-dem), 1.0f); + } + else + { + glColor4f(0.5f, 0.5f*dem, 0.5f*(1.0f-dem), 1.0f); + } + glVertex3(coordVec*(radius + m_observer->range()*0.3)); + + tmp.setLon(tmp.lon() + dlon); + tmp.setLat(tmp.lat() + dlat); + } + glEnd(); + } + glLineWidth(1); + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + } } @@ -590,6 +701,16 @@ void tcViewportWidget::mousePressEvent(QMouseEvent* event) m_mouseSlicing = true; } } + else if (event->button() == Qt::MidButton) + { + bool ok; + m_mouseStartCoord = geoAt(event->posF().x(), event->posF().y(), &ok); + m_mouseIntersecting = false; + if (ok) + { + m_mouseCrossing = true; + } + } } else if (m_interactionMode == TexturePoint) { @@ -611,6 +732,7 @@ void tcViewportWidget::mousePressEvent(QMouseEvent* event) } } +#include void tcViewportWidget::mouseReleaseEvent(QMouseEvent* event) { if (m_mouseInteracting) @@ -628,6 +750,19 @@ void tcViewportWidget::mouseReleaseEvent(QMouseEvent* event) } updateGL(); } + else if (m_mouseCrossing) + { + m_mouseCrossing = false; + if (m_mouseIntersecting) + { + setCrossSection(m_mouseStartCoord, m_mouseCoord); + } + else + { + m_crossSectioned = false; + } + updateGL(); + } } void tcViewportWidget::wheelEvent(QWheelEvent* event) diff --git a/tcViewportWidget.h b/tcViewportWidget.h index 070ad70..e6e57f9 100644 --- a/tcViewportWidget.h +++ b/tcViewportWidget.h @@ -89,6 +89,9 @@ class tcViewportWidget : public QGLWidget /// Set slice. void setSlice(const tcGeo& sw, const tcGeo& ne); + /// Set cross section. + void setCrossSection(const tcGeo& p1, const tcGeo& p2); + /* * General rendering slots */ @@ -241,6 +244,9 @@ class tcViewportWidget : public QGLWidget /// Slicing with the mouse? bool m_mouseSlicing; + /// Cross sectioning with mouse? + bool m_mouseCrossing; + /// Start of mouse slicing action. tcGeo m_mouseStartCoord; @@ -250,6 +256,12 @@ class tcViewportWidget : public QGLWidget /// Coordinates of slice. tcGeo m_slice[2]; + /// Whether a cross section is selected. + bool m_crossSectioned; + + /// Cross section. + tcGeo m_crossSection[2]; + /// Texture point object. QObject* m_texturePointObject; -- 2.11.4.GIT