Unverified Commit c4726530 authored by Peterson, Peter's avatar Peterson, Peter Committed by GitHub
Browse files

Merge pull request #32345 from mantidproject/sans758_instrview_camera

Instrument viewer projection fix
parents 951b5b55 733de318
......@@ -90,6 +90,7 @@ public:
bool isDetector(const size_t componentIndex) const {
return componentIndex < m_assemblySortedDetectorIndices->size();
}
bool isMonitor(const size_t componentIndex) const;
size_t compOffsetIndex(const size_t componentIndex) const {
return componentIndex - m_assemblySortedDetectorIndices->size();
}
......
......@@ -162,6 +162,13 @@ size_t ComponentInfo::numberOfDetectorsInSubtree(const size_t componentIndex) co
return std::distance(range.begin(), range.end());
}
bool ComponentInfo::isMonitor(const size_t componentIndex) const {
if (hasDetectorInfo()) {
return this->m_detectorInfo->isMonitor(componentIndex);
}
return false;
}
const Eigen::Vector3d &ComponentInfo::position(const size_t componentIndex) const {
checkNoTimeDependence();
if (isDetector(componentIndex)) {
......
......@@ -49,14 +49,15 @@ private:
/// Shapes for each component
std::shared_ptr<std::vector<std::shared_ptr<const Geometry::IObject>>> m_shapes;
BoundingBox componentBoundingBox(const size_t index, const BoundingBox *reference) const;
BoundingBox componentBoundingBox(const size_t index, const BoundingBox *reference,
const bool excludeMonitors = false) const;
/// Private copy constructor. Do not make public.
ComponentInfo(const ComponentInfo &other);
void growBoundingBoxAsRectuangularBank(size_t index, const Geometry::BoundingBox *reference,
Geometry::BoundingBox &mutableBB) const;
void growBoundingBoxAsOutline(size_t index, const Geometry::BoundingBox *reference,
Geometry::BoundingBox &mutableBB) const;
Geometry::BoundingBox &mutableBB, const bool excludeMonitors = false) const;
void growBoundingBoxAsOutline(size_t index, const Geometry::BoundingBox *reference, Geometry::BoundingBox &mutableBB,
const bool excludeMonitors = false) const;
public:
struct QuadrilateralComponent {
......@@ -121,7 +122,8 @@ public:
const Geometry::IObject &shape(const size_t componentIndex) const;
double solidAngle(const size_t componentIndex, const Kernel::V3D &observer) const;
BoundingBox boundingBox(const size_t componentIndex, const BoundingBox *reference = nullptr) const;
BoundingBox boundingBox(const size_t componentIndex, const BoundingBox *reference = nullptr,
const bool excludeMonitors = false) const;
Beamline::ComponentType componentType(const size_t componentIndex) const;
void setScanInterval(const std::pair<Types::Core::DateAndTime, Types::Core::DateAndTime> &interval);
size_t scanCount() const;
......
......@@ -279,15 +279,17 @@ double ComponentInfo::solidAngle(const size_t componentIndex, const Kernel::V3D
* @param index : Index of the component to get the bounding box for
* @param reference : Reference bounding box (optional)
* @param mutableBB : Output bounding box. This will be grown.
* @param excludeMonitors : Optional flag to exclude monitors and choppers
*/
void ComponentInfo::growBoundingBoxAsRectuangularBank(size_t index, const Geometry::BoundingBox *reference,
Geometry::BoundingBox &mutableBB) const {
Geometry::BoundingBox &mutableBB,
const bool excludeMonitors) const {
auto panel = quadrilateralComponent(index);
mutableBB.grow(componentBoundingBox(panel.bottomLeft, reference));
mutableBB.grow(componentBoundingBox(panel.topRight, reference));
mutableBB.grow(componentBoundingBox(panel.topLeft, reference));
mutableBB.grow(componentBoundingBox(panel.bottomRight, reference));
mutableBB.grow(componentBoundingBox(panel.bottomLeft, reference, excludeMonitors));
mutableBB.grow(componentBoundingBox(panel.topRight, reference, excludeMonitors));
mutableBB.grow(componentBoundingBox(panel.topLeft, reference, excludeMonitors));
mutableBB.grow(componentBoundingBox(panel.bottomRight, reference, excludeMonitors));
}
/**
......@@ -298,9 +300,11 @@ void ComponentInfo::growBoundingBoxAsRectuangularBank(size_t index, const Geomet
* @param index : Index of the component to get the bounding box for
* @param reference : Reference bounding box (optional)
* @param mutableBB : Output bounding box. This will be grown.
* @param excludeMonitors : Optional flag to exclude monitors and choppers
*/
void ComponentInfo::growBoundingBoxAsOutline(size_t index, const BoundingBox *reference, BoundingBox &mutableBB) const {
mutableBB.grow(componentBoundingBox(index, reference));
void ComponentInfo::growBoundingBoxAsOutline(size_t index, const BoundingBox *reference, BoundingBox &mutableBB,
const bool excludeMonitors) const {
mutableBB.grow(componentBoundingBox(index, reference, excludeMonitors));
}
/**
......@@ -309,13 +313,25 @@ void ComponentInfo::growBoundingBoxAsOutline(size_t index, const BoundingBox *re
* @param index : Component index
* @param reference : Optional reference for coordinate system for non-axis
*aligned bounding boxes
* @param excludeMonitors : Optional flag to exclude monitor and choppers
* @return Absolute bounding box.
*/
BoundingBox ComponentInfo::componentBoundingBox(const size_t index, const BoundingBox *reference) const {
BoundingBox ComponentInfo::componentBoundingBox(const size_t index, const BoundingBox *reference,
const bool excludeMonitors) const {
// Check that we have a valid shape here
if (componentType(index) == Beamline::ComponentType::Infinite) {
return BoundingBox(); // Return null bounding box
}
if (excludeMonitors) {
// skip monitors
if (isDetector(index) && m_componentInfo->isMonitor(index)) {
return BoundingBox();
}
// skip other components such as choppers, etc
if (componentType(index) == Beamline::ComponentType::Generic) {
return BoundingBox();
}
}
if (!hasValidShape(index)) {
return BoundingBox(this->position(index).X(), this->position(index).Y(), this->position(index).Z(),
this->position(index).X(), this->position(index).Y(), this->position(index).Z());
......@@ -366,11 +382,13 @@ BoundingBox ComponentInfo::componentBoundingBox(const size_t index, const Boundi
* @param componentIndex : Component index to get the bounding box for
* @param reference : Optional reference for coordinate system for non-axis
*aligned bounding boxes
* @param excludeMonitors : Optional flag to exclude monitors and choppers
* @return Absolute bounding box
*/
BoundingBox ComponentInfo::boundingBox(const size_t componentIndex, const BoundingBox *reference) const {
BoundingBox ComponentInfo::boundingBox(const size_t componentIndex, const BoundingBox *reference,
const bool excludeMonitors) const {
if (isDetector(componentIndex) || componentType(componentIndex) == Beamline::ComponentType::Infinite) {
return componentBoundingBox(componentIndex, reference);
return componentBoundingBox(componentIndex, reference, excludeMonitors);
}
BoundingBox absoluteBB;
......@@ -385,20 +403,20 @@ BoundingBox ComponentInfo::boundingBox(const size_t componentIndex, const Boundi
// box calculations.
} else if (compFlag == Beamline::ComponentType::Unstructured) {
for (const auto &childIndex : this->children(componentIndex)) {
absoluteBB.grow(boundingBox(childIndex, reference));
absoluteBB.grow(boundingBox(childIndex, reference, excludeMonitors));
}
} else if (compFlag == Beamline::ComponentType::Grid) {
for (const auto &childIndex : this->children(componentIndex)) {
growBoundingBoxAsRectuangularBank(childIndex, reference, absoluteBB);
growBoundingBoxAsRectuangularBank(childIndex, reference, absoluteBB, excludeMonitors);
}
} else if (compFlag == Beamline::ComponentType::Rectangular || compFlag == Beamline::ComponentType::Structured ||
parentFlag == Beamline::ComponentType::Grid) {
growBoundingBoxAsRectuangularBank(componentIndex, reference, absoluteBB);
growBoundingBoxAsRectuangularBank(componentIndex, reference, absoluteBB, excludeMonitors);
} else if (compFlag == Beamline::ComponentType::OutlineComposite) {
growBoundingBoxAsOutline(componentIndex, reference, absoluteBB);
growBoundingBoxAsOutline(componentIndex, reference, absoluteBB, excludeMonitors);
} else {
// General case
absoluteBB.grow(componentBoundingBox(componentIndex, reference));
absoluteBB.grow(componentBoundingBox(componentIndex, reference, excludeMonitors));
}
return absoluteBB;
}
......
......@@ -54,6 +54,7 @@ Bugfixes
- Fixed the help icon not showing on OSX and high-resolution monitors.
- Tabbing between fields in the error reporter now works as expected, rather than jumping to a random place each time.
- Fixed the advanced plotting dialog incorrectly laying out, causing the options to be partially occluded.
- Fixed a bug in the Instrument Viewer causing the projection to not be updated when different axis views were selected in Full 3D.
:ref:`Release 6.2.0 <v6.2.0>`
......@@ -63,15 +63,13 @@ public:
static constexpr double INVALID_VALUE = std::numeric_limits<double>::lowest();
/// Constructor
InstrumentActor(const QString &wsName, bool autoscaling = true,
double scaleMin = 0.0, double scaleMax = 0.0);
InstrumentActor(const QString &wsName, bool autoscaling = true, double scaleMin = 0.0, double scaleMax = 0.0);
///< Destructor
~InstrumentActor();
/// Draw the instrument in 3D
void draw(bool picking = false) const;
/// Return the bounding box in 3D
void getBoundingBox(Mantid::Kernel::V3D &minBound,
Mantid::Kernel::V3D &maxBound) const;
void getBoundingBox(Mantid::Kernel::V3D &minBound, Mantid::Kernel::V3D &maxBound, const bool excludeMonitors) const;
/// Set a component (and all its children) visible.
void setComponentVisible(size_t componentIndex);
/// Set visibilit of all components.
......@@ -163,11 +161,9 @@ public:
/// Get the integrated counts of a detector by its detector Index.
double getIntegratedCounts(size_t index) const;
/// Sum the counts in detectors
void sumDetectors(const std::vector<size_t> &dets, std::vector<double> &x,
std::vector<double> &y, size_t size) const;
void sumDetectors(const std::vector<size_t> &dets, std::vector<double> &x, std::vector<double> &y, size_t size) const;
/// Sum the counts in detectors.
void sumDetectors(const std::vector<size_t> &dets, std::vector<double> &x,
std::vector<double> &y) const;
void sumDetectors(const std::vector<size_t> &dets, std::vector<double> &x, std::vector<double> &y) const;
/// Calc indexes for min and max bin values
void getBinMinMaxIndex(size_t wi, size_t &imin, size_t &imax) const;
......@@ -179,17 +175,12 @@ public:
/// Get the guide visibility status
bool areGuidesShown() const { return m_showGuides; }
static void BasisRotation(const Mantid::Kernel::V3D &Xfrom,
const Mantid::Kernel::V3D &Yfrom,
const Mantid::Kernel::V3D &Zfrom,
const Mantid::Kernel::V3D &Xto,
const Mantid::Kernel::V3D &Yto,
const Mantid::Kernel::V3D &Zto,
Mantid::Kernel::Quat &R, bool out = false);
static void BasisRotation(const Mantid::Kernel::V3D &Xfrom, const Mantid::Kernel::V3D &Yfrom,
const Mantid::Kernel::V3D &Zfrom, const Mantid::Kernel::V3D &Xto,
const Mantid::Kernel::V3D &Yto, const Mantid::Kernel::V3D &Zto, Mantid::Kernel::Quat &R,
bool out = false);
static void rotateToLookAt(const Mantid::Kernel::V3D &eye,
const Mantid::Kernel::V3D &up,
Mantid::Kernel::Quat &R);
static void rotateToLookAt(const Mantid::Kernel::V3D &eye, const Mantid::Kernel::V3D &up, Mantid::Kernel::Quat &R);
/* Masking */
......@@ -200,8 +191,7 @@ public:
std::string getDefaultAxis() const;
std::string getDefaultView() const;
std::string getInstrumentName() const;
std::vector<std::string> getStringParameter(const std::string &name,
bool recursive = true) const;
std::vector<std::string> getStringParameter(const std::string &name, bool recursive = true) const;
/// Load the state of the actor from a Mantid project file.
void loadFromProject(const std::string &lines);
/// Save the state of the actor to a Mantid project file.
......@@ -220,25 +210,20 @@ signals:
private:
static constexpr double TOLERANCE = 0.00001;
void setUpWorkspace(const std::shared_ptr<const Mantid::API::MatrixWorkspace>
&sharedWorkspace,
double scaleMin, double scaleMax);
void setUpWorkspace(const std::shared_ptr<const Mantid::API::MatrixWorkspace> &sharedWorkspace, double scaleMin,
double scaleMax);
void setupPhysicalInstrumentIfExists();
void resetColors();
void loadSettings();
void saveSettings();
void setDataMinMaxRange(double vmin, double vmax);
void setDataIntegrationRange(const double &xmin, const double &xmax);
void
calculateIntegratedSpectra(const Mantid::API::MatrixWorkspace &workspace);
void calculateIntegratedSpectra(const Mantid::API::MatrixWorkspace &workspace);
/// Sum the counts in detectors if the workspace has equal bins for all
/// spectra
void sumDetectorsUniform(const std::vector<size_t> &dets,
std::vector<double> &x,
std::vector<double> &y) const;
void sumDetectorsUniform(const std::vector<size_t> &dets, std::vector<double> &x, std::vector<double> &y) const;
/// Sum the counts in detectors if the workspace is ragged
void sumDetectorsRagged(const std::vector<size_t> &dets,
std::vector<double> &x, std::vector<double> &y,
void sumDetectorsRagged(const std::vector<size_t> &dets, std::vector<double> &x, std::vector<double> &y,
size_t size) const;
/// The workspace whose data are shown
......
......@@ -56,13 +56,12 @@ public:
/// Return the projection type.
ProjectionType getProjectionType() const;
/// Set a projection.
void setProjection(double /*l*/, double /*r*/, double /*b*/, double /*t*/,
double /*nearz*/, double /*farz*/,
void setProjection(double /*l*/, double /*r*/, double /*b*/, double /*t*/, double /*nearz*/, double /*farz*/,
ProjectionType type = Viewport::ORTHO);
/// Set a projection.
void setProjection(const Mantid::Kernel::V3D &minBounds,
const Mantid::Kernel::V3D &maxBounds,
void setProjection(const Mantid::Kernel::V3D &minBounds, const Mantid::Kernel::V3D &maxBounds,
ProjectionType type = Viewport::ORTHO);
void setProjectionZPlane(const Mantid::Kernel::V3D &minBounds, const Mantid::Kernel::V3D &maxBounds);
/// Apply the projection to OpenGL engine
void applyProjection() const;
/// Rotate the model
......@@ -85,6 +84,8 @@ public:
/// Call to set the View to Z- direction
void setViewToZNegative();
void adjustProjection();
/// Init rotation at a point on the screen
void initRotationFrom(int a, int b);
/// Generate a new rotation matrix
......@@ -115,8 +116,7 @@ public:
void setTranslation(double /*xval*/, double /*yval*/);
// void getProjection(double&,double&,double&,double&,double&,double&);
void getInstantProjection(double & /*xmin*/, double & /*xmax*/,
double & /*ymin*/, double & /*ymax*/,
void getInstantProjection(double & /*xmin*/, double & /*xmax*/, double & /*ymin*/, double & /*ymax*/,
double & /*zmin*/, double & /*zmax*/) const;
/// Apply the transformation to a vector
......@@ -128,8 +128,7 @@ public:
protected:
/// Correct for aspect ratio
void correctForAspectRatioAndZoom(double &xmin, double &xmax, double &ymin,
double &ymax, double &zmin,
void correctForAspectRatioAndZoom(double &xmin, double &xmax, double &ymin, double &ymax, double &zmin,
double &zmax) const;
/// Project a point onto a sphere centered at rotation point
void projectOnSphere(int a, int b, Mantid::Kernel::V3D &point) const;
......@@ -152,6 +151,14 @@ protected:
/// z axis)
double m_far; ///< Ortho/Prespective Projection zmax value (Far side of the z
/// axis)
double m_leftOrig;
double m_rightOrig;
double m_bottomOrig;
double m_topOrig;
double m_zminOrig;
double m_zmaxOrig;
double m_zmin;
double m_zmax;
/* Trackball rotation */
......
......@@ -221,9 +221,10 @@ MatrixWorkspace_const_sptr InstrumentActor::getWorkspace() const {
return sharedWorkspace;
}
void InstrumentActor::getBoundingBox(Mantid::Kernel::V3D &minBound, Mantid::Kernel::V3D &maxBound) const {
void InstrumentActor::getBoundingBox(Mantid::Kernel::V3D &minBound, Mantid::Kernel::V3D &maxBound,
const bool excludeMonitors) const {
const auto &compInfo = componentInfo();
auto bb = compInfo.boundingBox(compInfo.root());
auto bb = compInfo.boundingBox(compInfo.root(), nullptr, excludeMonitors);
minBound = bb.minPoint();
maxBound = bb.maxPoint();
}
......
......@@ -50,10 +50,15 @@ namespace MantidWidgets {
Projection3D::Projection3D(const InstrumentActor *rootActor, QSize viewportSize)
: ProjectionSurface(rootActor), m_drawAxes(true), m_wireframe(false), m_viewport(std::move(viewportSize)) {
V3D minBounds, maxBounds;
m_instrActor->getBoundingBox(minBounds, maxBounds);
// exclude monitors and choppers from bounding box to set tighter view bounds
m_instrActor->getBoundingBox(minBounds, maxBounds, true);
m_viewport.setProjection(minBounds, maxBounds);
// use the full bounding box to get the Z bounds for the clipping plane
m_instrActor->getBoundingBox(minBounds, maxBounds, false);
m_viewport.setProjectionZPlane(minBounds, maxBounds);
changeColorMap();
// create and connect the move input controller
......
......@@ -23,10 +23,9 @@ namespace MantidWidgets {
* @param glWidgetDimensions Viewport width/height in device pixels
*/
Viewport::Viewport(QSize dimensions)
: m_projectionType(Viewport::ORTHO), m_dimensions(std::move(dimensions)),
m_left(-1), m_right(1), m_bottom(-1), m_top(1), m_near(-1), m_far(1),
m_rotationspeed(180.0 / M_PI), m_zoomFactor(1.0), m_xTrans(0.0),
m_yTrans(0.0), m_zTrans(0.0) {
: m_projectionType(Viewport::ORTHO), m_dimensions(std::move(dimensions)), m_left(-1), m_right(1), m_bottom(-1),
m_top(1), m_near(-1), m_far(1), m_rotationspeed(180.0 / M_PI), m_zoomFactor(1.0), m_xTrans(0.0), m_yTrans(0.0),
m_zTrans(0.0) {
m_quaternion.GLMatrix(&m_rotationmatrix[0]);
}
......@@ -34,9 +33,7 @@ Viewport::Viewport(QSize dimensions)
* Resize the viewport = size of the displaying widget.
* @param dimensions Viewport width/height in device pixels
*/
void Viewport::resize(QSize dimensions) {
m_dimensions = std::move(dimensions);
}
void Viewport::resize(QSize dimensions) { m_dimensions = std::move(dimensions); }
/**
* Get the size of the viewport in logical pixels (size of the displaying
......@@ -61,8 +58,7 @@ QSize Viewport::dimensions() const { return m_dimensions; }
* @param type :: Projection type: ORTHO or PERSPECTIVE. PERSPECTIVE isn't fully
*implemented
*/
void Viewport::setProjection(double l, double r, double b, double t,
double nearz, double farz,
void Viewport::setProjection(double l, double r, double b, double t, double nearz, double farz,
Viewport::ProjectionType type) {
m_projectionType = type;
m_left = l;
......@@ -75,6 +71,11 @@ void Viewport::setProjection(double l, double r, double b, double t,
std::swap(m_bottom, m_top);
m_near = nearz;
m_far = farz;
// save the current projection bounds to reuse on view changes
m_leftOrig = m_left;
m_rightOrig = m_right;
m_topOrig = m_top;
m_bottomOrig = m_bottom;
}
/**
......@@ -85,24 +86,43 @@ void Viewport::setProjection(double l, double r, double b, double t,
* @param type :: Projection type: ORTHO or PERSPECTIVE. PERSPECTIVE isn't fully
*implemented
*/
void Viewport::setProjection(const Mantid::Kernel::V3D &minBounds,
const Mantid::Kernel::V3D &maxBounds,
void Viewport::setProjection(const Mantid::Kernel::V3D &minBounds, const Mantid::Kernel::V3D &maxBounds,
ProjectionType type) {
double radius = minBounds.norm();
double tmp = maxBounds.norm();
if (tmp > radius)
radius = tmp;
setProjection(minBounds.X(), maxBounds.X(), minBounds.Y(), maxBounds.Y(),
-radius, radius, type);
// save the Z value of the bounding box to use when rotating views
m_zmin = minBounds.Z();
m_zmax = maxBounds.Z();
m_zminOrig = m_zmin;
m_zmaxOrig = m_zmax;
setProjection(minBounds.X(), maxBounds.X(), minBounds.Y(), maxBounds.Y(), -radius, radius, type);
}
/**
* Sets the near and far clipping plane based on the size of given points
*
* @param minBounds :: Near-bottom-left corner of the scene.
* @param maxBounds :: Far-top-right corner of the scene.
*/
void Viewport::setProjectionZPlane(const Mantid::Kernel::V3D &minBounds, const Mantid::Kernel::V3D &maxBounds) {
double radius = minBounds.norm();
double tmp = maxBounds.norm();
if (tmp > radius)
radius = tmp;
m_near = -radius;
m_far = radius;
}
/**
* Return XY plane bounds corrected for the aspect ratio.
*/
void Viewport::correctForAspectRatioAndZoom(double &xmin, double &xmax,
double &ymin, double &ymax,
double &zmin, double &zmax) const {
void Viewport::correctForAspectRatioAndZoom(double &xmin, double &xmax, double &ymin, double &ymax, double &zmin,
double &zmax) const {
xmin = m_left;
xmax = m_right;
ymin = m_bottom;
......@@ -127,9 +147,7 @@ void Viewport::correctForAspectRatioAndZoom(double &xmin, double &xmax,
zmax = m_far * m_zoomFactor;
}
Viewport::ProjectionType Viewport::getProjectionType() const {
return m_projectionType;
}
Viewport::ProjectionType Viewport::getProjectionType() const { return m_projectionType; }
/**
* Get the projection bounds.
......@@ -140,8 +158,7 @@ Viewport::ProjectionType Viewport::getProjectionType() const {
* @param zmin :: near side of the Ortho Projection
* @param zmax :: far side of the Ortho Projection
*/
void Viewport::getInstantProjection(double &xmin, double &xmax, double &ymin,
double &ymax, double &zmin,
void Viewport::getInstantProjection(double &xmin, double &xmax, double &ymin, double &ymax, double &zmin,
double &zmax) const {
correctForAspectRatioAndZoom(xmin, xmax, ymin, ymax, zmin, zmax);
}
......@@ -181,9 +198,7 @@ void Viewport::applyProjection() const {
if (OpenGLError::hasError("GLViewport::issueGL()")) {
OpenGLError::log() << "Arguments to glOrtho:\n";
OpenGLError::log() << xmin << ' ' << xmax << '\n'
<< ymin << ' ' << ymax << '\n'
<< zmin << ' ' << zmax << "\n\n";
OpenGLError::log() << xmin << ' ' << xmax << '\n' << ymin << ' ' << ymax << '\n' << zmin << ' ' << zmax << "\n\n";
}
}
// Reset the rendering options just in case
......@@ -201,10 +216,8 @@ void Viewport::applyProjection() const {
void Viewport::projectOnSphere(int a, int b, Mantid::Kernel::V3D &point) const {
// z initiaised to zero if out of the sphere
double z = 0;
auto x = static_cast<double>((2.0 * a - m_dimensions.width()) /
m_dimensions.width());
auto y = static_cast<double>((m_dimensions.height() - 2.0 * b) /
m_dimensions.height());
auto x = static_cast<double>((2.0 * a - m_dimensions.width()) / m_dimensions.width());
auto y = static_cast<double>((m_dimensions.height() - 2.0 * b) / m_dimensions.height());
double norm = x * x + y * y;
if (norm > 1.0) // The point is inside the sphere
{
......@@ -249,10 +262,10 @@ void Viewport::reset() {
*/
void Viewport::setViewToXPositive() {
reset();
Mantid::Kernel::Quat tempy(Mantid::Kernel::V3D(0.0, 0.0, 1.0),
Mantid::Kernel::V3D(-1.0, 0.0, 0.0));
Mantid::Kernel::Quat tempy(Mantid::Kernel::V3D(0.0, 0.0, 1.0), Mantid::Kernel::V3D(-1.0, 0.0, 0.0));
m_quaternion = tempy;
m_quaternion.GLMatrix(&m_rotationmatrix[0]);
adjustProjection();
}
/**
......@@ -261,10 +274,10 @@ void Viewport::setViewToXPositive() {
*/
void Viewport::setViewToYPositive() {
reset();
Mantid::Kernel::Quat tempy(Mantid::Kernel::V3D(0.0, 0.0, 1.0),
Mantid::Kernel::V3D(0.0, -1.0, 0.0));
Mantid::Kernel::Quat tempy(Mantid::Kernel::V3D(0.0, 0.0, 1.0), Mantid::Kernel::V3D(0.0, -1.0, 0.0));
m_quaternion = tempy;
m_quaternion.GLMatrix(&m_rotationmatrix[0]);
adjustProjection();
}
/**
......@@ -275,6 +288,7 @@ void Viewport::setViewToZPositive() {
reset();
m_quaternion.init();
m_quaternion.GLMatrix(&m_rotationmatrix[0]);
adjustProjection();
}
/**
......@@ -283,10 +297,10 @@ void Viewport::setViewToZPositive() {
*/
void Viewport::setViewToXNegative() {
reset();
Mantid::Kernel::Quat tempy(Mantid::Kernel::V3D(0.0, 0.0, 1.0),
Mantid::Kernel::V3D(1.0, 0.0, 0.0));
Mantid::Kernel::Quat tempy(Mantid::Kernel::V3D(0.0, 0.0, 1.0), Mantid::Kernel::V3D(1.0, 0.0, 0.0));
m_quaternion = tempy;
m_quaternion.GLMatrix(&m_rotationmatrix[0]);
adjustProjection();
}
/**
......@@ -295,10 +309,10 @@ void Viewport::setViewToXNegative() {
*/
void Viewport::setViewToYNegative() {
reset();
Mantid::Kernel::Quat tempy(Mantid::Kernel::V3D(0.0, 0.0, 1.0),
Mantid::Kernel::V3D(0.0, 1.0, 0.0));
Mantid::Kernel::Quat tempy(Mantid::Kernel::V3D(0.0, 0.0, 1.0), Mantid::Kernel::V3D(0.0, 1.0, 0.0));
m_quaternion = tempy;
m_quaternion.GLMatrix(&m_rotationmatrix[0]);
adjustProjection();
}
/**
......@@ -310,6 +324,23 @@ void Viewport::setViewToZNegative() {
Mantid::Kernel::Quat tempy(180.0, Mantid::Kernel::V3D(0.0, 1.0, 0.0));
m_quaternion = tempy;
m_quaternion.GLMatrix(&m_rotationmatrix[0]);
adjustProjection();
}
void Viewport::adjustProjection() {
// reset the projection bounds to the original values
m_left = m_leftOrig;
m_right = m_rightOrig;
m_top = m_topOrig;
m_bottom = m_bottomOrig;
m_zmin = m_zminOrig;
m_zmax = m_zmaxOrig;
// rotate the original projection based on the new quaternion
m_quaternion.rotateBB(m_left, m_bottom, m_zmin, m_right, m_top, m_zmax);
// update the GL projection with the new bounds
applyProjection();
}
/**
......@@ -346,8 +377,7 @@ void Viewport::initZoomFrom(int a, int b) {
* @param b :: The y mouse coordinate
*/
void Viewport::generateZoomTo(int a, int b) {