Commit 13226198 authored by Kendrick, Coleman's avatar Kendrick, Coleman
Browse files

Use smaller bounding box for rotations

parent 78ba344f
......@@ -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;
}
......
......@@ -70,8 +70,7 @@ public:
/// 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.
......
......@@ -63,6 +63,7 @@ public:
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
......
......@@ -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
......
......@@ -108,6 +108,22 @@ void Viewport::setProjection(const Mantid::Kernel::V3D &minBounds,
-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.
*/
......@@ -338,6 +354,7 @@ void Viewport::adjustProjection() {
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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment