Commit 1638b974 authored by Gigg, Martyn Anthony's avatar Gigg, Martyn Anthony
Browse files

Store a reference to the intersected object in a Track link

This should avoid having to go through the object component to get access
to the shape when testing for intersections.
Refs #9842
parent babc40e2
......@@ -6,6 +6,7 @@
//----------------------------------------------------------------------
#include "MantidGeometry/DllConfig.h"
#include "MantidGeometry/IComponent.h"
#include "MantidGeometry/Objects/Object.h"
#include "MantidKernel/Tolerance.h"
#include <list>
......@@ -51,23 +52,18 @@ namespace Mantid
*/
struct MANTID_GEOMETRY_DLL Link
{
/**
* Default constructor
*/
inline Link() : entryPoint(),exitPoint(),distFromStart(),
distInsideObject(), componentID(NULL)
{}
/**
* Constuctor
* @param entry :: Kernel::V3D point to start
* @param exit :: Kernel::V3D point to end track
* @param totalDistance :: Total distance from start of track
* @param obj :: A reference to the object that was intersected
* @param compID :: An optional component identifier for the physical object hit. (Default=NULL)
*/
inline Link(const Kernel::V3D& entry,const Kernel::V3D& exit, const double totalDistance, const ComponentID compID = NULL) :
entryPoint(entry),exitPoint(exit),distFromStart(totalDistance), distInsideObject(entryPoint.distance(exitPoint)),
componentID(compID)
inline Link(const Kernel::V3D& entry,const Kernel::V3D& exit, const double totalDistance,
const Object & obj, const ComponentID compID = NULL) :
entryPoint(entry),exitPoint(exit),distFromStart(totalDistance), distInsideObject(entryPoint.distance(exitPoint)),
object(&obj), componentID(compID)
{}
/// Less than operator
inline bool operator<(const Link& other) const { return distFromStart < other.distFromStart; }
......@@ -76,20 +72,21 @@ namespace Mantid
/** @name Attributes. */
//@{
Kernel::V3D entryPoint; ///< Entry point
Kernel::V3D exitPoint; ///< Exit point
Kernel::V3D entryPoint; ///< Entry point
Kernel::V3D exitPoint; ///< Exit point
double distFromStart; ///< Total distance from track beginning
double distInsideObject; ///< Total distance covered inside object
const Object * object; ///< The object that was intersected
ComponentID componentID; ///< ComponentID of the intersected component
//@}
};
/**
* Stores a point of intersection along a track. The component intersected
* is linked using its ComponentID.
*
* Ordering for IntersectionPoint is special since we need that when dist is close
* Ordering for IntersectionPoint is special since we need that when dist is close
* that the +/- flag is taken into
* account.
*/
......@@ -97,22 +94,25 @@ namespace Mantid
{
/**
* Constuctor
* @param flag :: Indicates the direction of travel of the track with respect
* @param flag :: Indicates the direction of travel of the track with respect
* to the object: +1 is entering, -1 is leaving.
* @param end :: The end point for this partial segment
* @param distFromStartOfTrack :: Total distance from start of track
* @param compID :: An optional unique ID marking the component intersected. (Default=NULL)
* @param obj :: A reference to the object that was intersected
*/
inline IntersectionPoint(const int flag, const Kernel::V3D& end,
const double distFromStartOfTrack, const ComponentID compID = NULL) :
directionFlag(flag),endPoint(end),distFromStart(distFromStartOfTrack), componentID(compID)
const double distFromStartOfTrack, const Object & obj,
const ComponentID compID = NULL) :
directionFlag(flag),endPoint(end),distFromStart(distFromStartOfTrack),
object(&obj), componentID(compID)
{}
/**
* A IntersectionPoint is less-than another if either
* (a) the difference in distances is greater than the tolerance and this distance is less than the other or
* (b) the distance is less than the other and this point is defined as an exit point
*
*
* @param other :: IntersectionPoint object to compare
* @return True if the object is considered less than, otherwise false.
*/
......@@ -127,6 +127,7 @@ namespace Mantid
int directionFlag; ///< Directional flag
Kernel::V3D endPoint; ///< Point
double distFromStart; ///< Total distance from track begin
const Object * object; ///< The object that was intersected
ComponentID componentID; ///< Unique component ID
//@}
};
......@@ -155,10 +156,12 @@ namespace Mantid
/// Destructor
~Track();
/// Adds a point of intersection to the track
void addPoint(const int directionFlag, const Kernel::V3D& endPoint, const ComponentID compID = NULL);
void addPoint(const int directionFlag, const Kernel::V3D& endPoint,
const Object & obj, const ComponentID compID = NULL);
/// Adds a link to the track
int addLink(const Kernel::V3D& firstPoint,const Kernel::V3D& secondPoint,
const double distanceAlongTrack, const ComponentID compID = NULL);
int addLink(const Kernel::V3D& firstPoint,const Kernel::V3D& secondPoint,
const double distanceAlongTrack, const Object & obj,
const ComponentID compID = NULL);
/// Remove touching Links that have identical components
void removeCojoins();
/// Construct links between added points
......@@ -175,10 +178,10 @@ namespace Mantid
/// Returns an interator to the start of the set of links
LType::const_iterator begin() const { return m_links.begin(); }
/// Returns an interator to one-past-the-end of the set of links
LType::const_iterator end() const { return m_links.end(); }
LType::const_iterator end() const { return m_links.end(); }
/// Returns the number of links
int count() const { return static_cast<int>(m_links.size()); }
/// Is the link complete?
int count() const { return static_cast<int>(m_links.size()); }
/// Is the link complete?
int nonComplete() const;
private:
......
......@@ -72,8 +72,8 @@ namespace Mantid
m_shape = newShape;
}
/**
* Return the material of the component. Currently
/**
* Return the material of the component. Currently
* unaffected by parametrization
*/
const Kernel::Material_const_sptr ObjComponent::material() const
......@@ -132,7 +132,7 @@ namespace Mantid
//use the scale factor
out *= getScaleFactor();
out += this->getPos();
track.addLink(in,out,out.distance(track.startPoint()),this->getComponentID());
track.addLink(in,out,out.distance(track.startPoint()), *(this->shape()), this->getComponentID());
}
return intercepts;
......@@ -160,18 +160,18 @@ namespace Mantid
}
}
/**
* Given an input estimate of the axis aligned (AA) bounding box (BB), return an improved set of values.
* The AA BB is determined in the frame of the object and the initial estimate will be transformed there.
* The returned BB will be the frame of the ObjComponent and may not be optimal.
* @param absoluteBB :: [InOut] The bounding box for this object component will be stored here.
* if BB alignment is different from axis alignment, the system of coordinates to alighn is taken fron
* if BB alignment is different from axis alignment, the system of coordinates to alighn is taken fron
* the absoluteBB
*/
void ObjComponent::getBoundingBox(BoundingBox& absoluteBB) const
{
// Start with the box in the shape's coordinates
const Object_const_sptr s = shape();
if ( ! s ){
......@@ -200,22 +200,22 @@ namespace Mantid
// Rotate
(this->getRotation()).rotateBB(absoluteBB.xMin(),absoluteBB.yMin(),absoluteBB.zMin(),
absoluteBB.xMax(),absoluteBB.yMax(),absoluteBB.zMax());
// Shift
const V3D localPos = this->getPos();
absoluteBB.xMin() += localPos.X();
absoluteBB.xMin() += localPos.X();
absoluteBB.xMax() += localPos.X();
absoluteBB.yMin() += localPos.Y();
absoluteBB.yMin() += localPos.Y();
absoluteBB.yMax() += localPos.Y();
absoluteBB.zMin() += localPos.Z();
absoluteBB.zMin() += localPos.Z();
absoluteBB.zMax() += localPos.Z();
if(!Coord_system.empty()){
absoluteBB.realign(&Coord_system);
}
}
}
/**
* Gets the Height of the object by querying the underlying BoundingBox.
* @return height of object
......@@ -235,7 +235,7 @@ namespace Mantid
const BoundingBox & bbox = shape()->getBoundingBox();
return ( bbox.xMax() - bbox.xMin() ) / getScaleFactor().X();
}
/**
* Gets the Depth of the object by querying the underlying BoundingBox.
* @return depth of object
......
......@@ -8,7 +8,7 @@
#include "MantidKernel/Exception.h"
#include <algorithm>
#include <ostream>
#include <stdexcept>
#include <stdexcept>
#include "MantidGeometry/Instrument/RectangularDetectorPixel.h"
namespace Mantid
......@@ -44,7 +44,7 @@ RectangularDetector::RectangularDetector(const RectangularDetector* base, const
/** Valued constructor
* @param n :: name of the assembly
* @param reference :: the parent Component
*
*
* If the reference is an object of class Component,
* normal parenting apply. If the reference object is
* an assembly itself, then in addition to parenting
......@@ -63,7 +63,7 @@ RectangularDetector::RectangularDetector(const std::string& n, IComponent* refer
*/
RectangularDetector::~RectangularDetector()
{
}
/** Clone method
......@@ -406,7 +406,7 @@ void RectangularDetector::initialize(boost::shared_ptr<Object> shape,
//Calculate its id and set it.
int id;
id = this->getDetectorIDAtXY(ix, iy);
//minimum rectangular detector id
if(id<minDetId)
{
......@@ -437,7 +437,7 @@ void RectangularDetector::initialize(boost::shared_ptr<Object> shape,
m_minDetId=minDetId;
m_maxDetId=maxDetId;
}
//-------------------------------------------------------------------------------------------------
......@@ -544,8 +544,8 @@ void RectangularDetector::testIntersectionWithChildren(Track & testRay, std::deq
if (yIndex >= ypixels()) return;
// TODO: Do I need to put something smart here for the first 3 parameters?
testRay.addLink(intersec, intersec, 0.0,
getAtXY(xIndex, yIndex)->getComponentID());
auto comp = getAtXY(xIndex, yIndex);
testRay.addLink(intersec, intersec, 0.0, *(comp->shape()), comp->getComponentID());
}
......
......@@ -60,7 +60,7 @@ namespace Mantid
*/
Object::Object(const Object& A) :
ObjName(A.ObjName), TopRule((A.TopRule) ? A.TopRule->clone() : NULL), m_boundingBox(A.m_boundingBox),
AABBxMax(A.AABBxMax), AABByMax(A.AABByMax), AABBzMax(A.AABBzMax), AABBxMin(A.AABBxMin),
AABBxMax(A.AABBxMax), AABByMax(A.AABByMax), AABBzMax(A.AABBzMax), AABBxMin(A.AABBxMin),
AABByMin(A.AABByMin), AABBzMin(A.AABBzMin), boolBounded(A.boolBounded), handle(A.handle->clone()),
bGeometryCaching(A.bGeometryCaching), vtkCacheReader(A.vtkCacheReader),
vtkCacheWriter(A.vtkCacheWriter),
......@@ -110,7 +110,7 @@ namespace Mantid
/**
* Returns whether this object has a valid shape
* @returns True if the surface list is populated and there is a
* @returns True if the surface list is populated and there is a
* defined TopRule, false otherwise.
*/
bool Object::hasValidShape() const
......@@ -262,7 +262,7 @@ namespace Mantid
* @retval 1000+ keyNumber :: Error with keyNumber
* @retval 0 :: successfully populated all the whole Object.
*/
int Object::populate(const std::map<int, Surface*>& Smap)
int Object::populate(const std::map<int, Surface*>& Smap)
{
std::deque<Rule*> Rst;
Rst.push_back(TopRule);
......@@ -624,7 +624,7 @@ namespace Mantid
/**
* Takes the complement of a group
*/
void Object::makeComplement()
void Object::makeComplement()
{
Rule* NCG = procComp(TopRule);
TopRule = NCG;
......@@ -802,7 +802,7 @@ namespace Mantid
{
// Is the point and enterance/exit Point
const int flag = calcValidType(IPts[i], UT.direction());
UT.addPoint(flag, IPts[i]);
UT.addPoint(flag, IPts[i], *this);
}
}
UT.buildLink();
......@@ -1265,12 +1265,12 @@ namespace Mantid
double Object::CylinderSolidAngle(const V3D & observer, const Mantid::Kernel::V3D & centre,
const Mantid::Kernel::V3D & axis, const double radius, const double height) const
{
// The cylinder is triangulated along its axis EXCLUDING the end caps so that stacked cylinders
// give the correct value of solid angle (i.e shadowing is losely taken into account by this
// The cylinder is triangulated along its axis EXCLUDING the end caps so that stacked cylinders
// give the correct value of solid angle (i.e shadowing is losely taken into account by this
//method)
// Any triangle that has a normal facing away from the observer gives a negative solid
// Any triangle that has a normal facing away from the observer gives a negative solid
//angle and is excluded
// For simplicity the triangulation points are constructed such that the cone axis
// For simplicity the triangulation points are constructed such that the cone axis
// points up the +Z axis and then rotated into their final position
Kernel::V3D axis_direction = axis;
axis_direction.normalize();
......@@ -1495,7 +1495,7 @@ namespace Mantid
*/
const BoundingBox & Object::getBoundingBox() const
{
// This member function is const given that from a user's perspective it is perfecly reasonable
// This member function is const given that from a user's perspective it is perfecly reasonable
// to call it on a const object. We need to call a non-const function in places to update the cache,
// which is where the const_cast comes in to play.
......@@ -1507,10 +1507,10 @@ namespace Mantid
else if( m_boundingBox.isNull() )
{
// First up, construct the trial set of elements from the object's bounding box
const double big(1e10);
const double big(1e10);
double minX(-big), maxX(big), minY(-big), maxY(big), minZ(-big), maxZ(big);
TopRule->getBoundingBox(maxX, maxY, maxZ, minX, minY, minZ);
//If the object is not axis aligned then the bounding box will be poor, in particular the minima are left at the trial start so return
//If the object is not axis aligned then the bounding box will be poor, in particular the minima are left at the trial start so return
// a null object here
if (minX < -100 || maxX > 100 || minY < -100 || maxY > 100 || minZ < -100 || maxZ > 100)
{
......
......@@ -26,7 +26,7 @@ namespace Mantid
* Constructor
* @param startPt :: Initial point
* @param unitVector :: Directional vector. It must be unit vector.
*/
*/
Track::Track(const V3D& startPt, const V3D& unitVector) :
m_startPoint(startPt),m_unitVector(unitVector)
{}
......@@ -34,7 +34,7 @@ namespace Mantid
/**
* Copy Constructor
* @param other :: Track to initialise this copy with.
*/
*/
Track::Track(const Track& other) : m_startPoint(other.m_startPoint),m_unitVector(other.m_unitVector),
m_links(other.m_links),m_surfPoints(other.m_surfPoints)
{}
......@@ -43,7 +43,7 @@ namespace Mantid
* Assignment operator
* @param other :: The track to copy from
* @return *this
*/
*/
Track& Track::operator=(const Track& other)
{
if (this != &other)
......@@ -63,7 +63,7 @@ namespace Mantid
{}
/**
* Resets the track starting point and direction.
* Resets the track starting point and direction.
* @param startPoint :: The new starting point
* @param direction :: The new direction. Must be a unit vector!
*/
......@@ -153,11 +153,14 @@ namespace Mantid
* @param directionFlag :: A flag indicating if the direction of travel is entering/leaving
* an object. +1 is entering, -1 is leaving.
* @param endPoint :: Point of intersection
* @param obj :: A reference to the object that was intersected
* @param compID :: ID of the component that this link is about (Default=NULL)
*/
void Track::addPoint(const int directionFlag, const V3D& endPoint, const ComponentID compID)
void Track::addPoint(const int directionFlag, const V3D& endPoint, const Object & obj,
const ComponentID compID)
{
IntersectionPoint newPoint(directionFlag, endPoint, endPoint.distance(m_startPoint), compID);
IntersectionPoint newPoint(directionFlag, endPoint, endPoint.distance(m_startPoint),
obj, compID);
PType::iterator lowestPtr = std::lower_bound(m_surfPoints.begin(), m_surfPoints.end(), newPoint);
m_surfPoints.insert(lowestPtr, newPoint);
}
......@@ -167,14 +170,15 @@ namespace Mantid
* @param firstPoint :: first Point
* @param secondPoint :: second Point
* @param distanceAlongTrack :: Distance along track
* @param obj :: A reference to the object that was intersected
* @param compID :: ID of the component that this link is about (Default=NULL)
* @retval Index of link within the track
*/
int Track::addLink(const V3D& firstPoint, const V3D& secondPoint,
const double distanceAlongTrack, const ComponentID compID)
const double distanceAlongTrack, const Object &obj, const ComponentID compID)
{
// Process First Point
Link newLink(firstPoint,secondPoint,distanceAlongTrack,compID);
Link newLink(firstPoint,secondPoint,distanceAlongTrack,obj,compID);
int index(0);
if( m_links.empty() )
{
......@@ -193,7 +197,7 @@ namespace Mantid
/**
* Builds a set of linking track components.
* This version deals with touching surfaces
* This version deals with touching surfaces
*/
void Track::buildLink()
{
......@@ -213,7 +217,7 @@ namespace Mantid
{
if (ac->directionFlag==-1)
{
addLink(m_startPoint,ac->endPoint,ac->distFromStart,ac->componentID); // from the void
addLink(m_startPoint,ac->endPoint,ac->distFromStart,*ac->object,ac->componentID); // from the void
workPt = ac->endPoint;
}
++ac;
......@@ -221,7 +225,7 @@ namespace Mantid
{
++bc;
}
}
}
//have we now passed over all of the potential intersections without actually hitting the object
if (ac == m_surfPoints.end())
......@@ -231,7 +235,7 @@ namespace Mantid
return;
}
workPt = ac->endPoint;
workPt = ac->endPoint;
while(bc != m_surfPoints.end()) // Since bc > ac
{
if (ac->directionFlag==1 && bc->directionFlag==-1)
......@@ -240,19 +244,19 @@ namespace Mantid
if (fabs(ac->distFromStart - bc->distFromStart)>Tolerance)
{
// track leave ac into bc.
addLink(ac->endPoint,bc->endPoint,bc->distFromStart,ac->componentID);
addLink(ac->endPoint,bc->endPoint,bc->distFromStart,*ac->object,ac->componentID);
}
// Points with intermediate void
else
{
addLink(workPt,ac->endPoint,ac->distFromStart,ac->componentID);
addLink(workPt,ac->endPoint,ac->distFromStart,*ac->object,ac->componentID);
}
workPt = bc->endPoint;
// ADDING to ac twice: since processing pairs
++ac;
++ac;
++bc; // can I do this past the end ?
++bc; // can I do this past the end ?
if (bc!=m_surfPoints.end())
{
++bc;
......@@ -263,9 +267,9 @@ namespace Mantid
++ac;
++bc;
}
}
}
m_surfPoints.clear(); // While vector
m_surfPoints.clear(); // While vector
return;
}
......
......@@ -11,14 +11,14 @@
#include <boost/shared_ptr.hpp>
#include "MantidKernel/V3D.h"
#include "MantidGeometry/Objects/Object.h"
#include "MantidGeometry/Surfaces/Cylinder.h"
#include "MantidGeometry/Surfaces/Sphere.h"
#include "MantidGeometry/Surfaces/Plane.h"
#include "MantidGeometry/Math/Algebra.h"
#include "MantidGeometry/Surfaces/SurfaceFactory.h"
#include "MantidGeometry/Objects/Track.h"
#include "MantidKernel/V3D.h"
#include "MantidGeometry/Objects/Object.h"
#include "MantidGeometry/Surfaces/Cylinder.h"
#include "MantidGeometry/Surfaces/Sphere.h"
#include "MantidGeometry/Surfaces/Plane.h"
#include "MantidGeometry/Math/Algebra.h"
#include "MantidGeometry/Surfaces/SurfaceFactory.h"
#include "MantidGeometry/Objects/Track.h"
#include "MantidGeometry/Rendering/GluGeometryHandler.h"
#include "MantidGeometry/Objects/BoundingBox.h"
#include "MantidGeometry/Objects/ShapeFactory.h"
......@@ -224,7 +224,7 @@ public:
void testGetBoundingBoxForSphere()
{
Object_sptr geom_obj = createSphere();
Object_sptr geom_obj = createSphere();
const double tolerance(1e-10);
double xmax,ymax,zmax,xmin,ymin,zmin;
......@@ -279,10 +279,10 @@ public:
SphSurMap[41]->setSurface(S41);
SphSurMap[41]->setName(41);
// A sphere
// A sphere
std::string ObjSphere="-41" ;
Object_sptr geom_obj = Object_sptr(new Object);
Object_sptr geom_obj = Object_sptr(new Object);
geom_obj->setObject(41,ObjSphere);
geom_obj->populate(SphSurMap);
......@@ -292,7 +292,7 @@ public:
// format = startPoint, endPoint, total distance so far
// forward only intercepts means that start point should be track origin
expectedResults.push_back(Link(V3D(-1,1.5,1),
V3D(sqrt(16-0.25)+1,1.5,1.0),sqrt(15.75)+2));
V3D(sqrt(16-0.25)+1,1.5,1.0),sqrt(15.75)+2,*geom_obj));
checkTrackIntercept(geom_obj,track,expectedResults);
}
......@@ -304,7 +304,7 @@ public:
Track track(V3D(0,-10,0),V3D(0,1,0));
//format = startPoint, endPoint, total distance so far
expectedResults.push_back(Link(V3D(0,-4.1,0),V3D(0,4.1,0),14.1));
expectedResults.push_back(Link(V3D(0,-4.1,0),V3D(0,4.1,0),14.1,*geom_obj));
checkTrackIntercept(geom_obj,track,expectedResults);
}
......@@ -316,7 +316,7 @@ public:
Track track(V3D(-10,0,0),V3D(1,0,0));
//format = startPoint, endPoint, total distance so far
expectedResults.push_back(Link(V3D(-4.1,0,0),V3D(4.1,0,0),14.1));
expectedResults.push_back(Link(V3D(-4.1,0,0),V3D(4.1,0,0),14.1,*geom_obj));
checkTrackIntercept(geom_obj,track,expectedResults);
}
......@@ -325,7 +325,7 @@ public:
std::vector<Link> expectedResults;
Object_sptr geom_obj = createCappedCylinder();
//format = startPoint, endPoint, total distance so far
expectedResults.push_back(Link(V3D(0,-3,0),V3D(0,3,0),13));
expectedResults.push_back(Link(V3D(0,-3,0),V3D(0,3,0),13,*geom_obj));
Track track(V3D(0,-10,0),V3D(0,1,0));
checkTrackIntercept(geom_obj,track,expectedResults);
......@@ -338,7 +338,7 @@ public:
Track track(V3D(-10,0,0),V3D(1,0,0));
//format = startPoint, endPoint, total distance so far
expectedResults.push_back(Link(V3D(-3.2,0,0),V3D(1.2,0,0),11.2));
expectedResults.push_back(Link(V3D(-3.2,0,0),V3D(1.2,0,0),11.2,*geom_obj));
checkTrackIntercept(geom_obj,track,expectedResults);
}
......@@ -399,8 +399,8 @@ public:
TS_ASSERT(object2.interceptSurface(TL)!=0);
std::vector<Link> expectedResults;
expectedResults.push_back(Link(V3D(-1,0,0),V3D(1,0,0),6));
expectedResults.push_back(Link(V3D(4.5,0,0),V3D(6.5,0,0),11.5));
expectedResults.push_back(Link(V3D(-1,0,0),V3D(1,0,0),6,object1));
expectedResults.push_back(Link(V3D(4.5,0,0),V3D(6.5,0,0),11.5,object2));
checkTrackIntercept(TL,expectedResults);
}
......@@ -430,8 +430,8 @@ public:
TS_ASSERT(object2.interceptSurface(TL)!=0);
std::vector<Link> expectedResults;
expectedResults.push_back(Link(V3D(-1,0,0),V3D(1,0,0),6));
expectedResults.push_back(Link(V3D(1,0,0),V3D(6.5,0,0),11.5));
expectedResults.push_back(Link(V3D(-1,0,0),V3D(1,0,0),6, object1));
expectedResults.push_back(Link(V3D(1,0,0),V3D(6.5,0,0),11.5, object2));
checkTrackIntercept(TL,expectedResults);
......@@ -463,9 +463,9 @@ public:
TS_ASSERT(object2.interceptSurface(TL)!=0);
std::vector<Link> expectedResults;
expectedResults.push_back(Link(V3D(-1,0,0),V3D(-0.8,0,0),4.2));
expectedResults.push_back(Link(V3D(-0.8,0,0),V3D(0.8,0,0),5.8));
expectedResults.push_back(Link(V3D(0.8,0,0),V3D(1,0,0),6));
expectedResults.push_back(Link(V3D(-1,0,0),V3D(-0.8,0,0),4.2,object1));
expectedResults.push_back(Link(V3D(-0.8,0,0),V3D(0.8,0,0),5.8,obje