Mantid
Loading...
Searching...
No Matches
ObjComponent.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
17#include <cfloat>
18#include <utility>
19
20namespace Mantid::Geometry {
21using Kernel::Quat;
22using Kernel::V3D;
23
28ObjComponent::ObjComponent(const IComponent *base, const ParameterMap *map) : Component(base, map), m_shape() {}
29
34ObjComponent::ObjComponent(const std::string &name, IComponent *parent)
35 : IObjComponent(), Component(name, parent), m_shape() {}
36
43ObjComponent::ObjComponent(const std::string &name, std::shared_ptr<const IObject> shape, IComponent *parent)
44 : IObjComponent(), Component(name, parent), m_shape(std::move(shape)) {}
45
49 if (m_map) {
50 auto base = dynamic_cast<const ObjComponent *>(m_base);
51 if (!base) {
52 throw std::logic_error("Failed to cast base component to ObjComponent");
53 }
54 return base->m_shape;
55 } else
56 return m_shape;
57}
58
60void ObjComponent::setShape(std::shared_ptr<const IObject> newShape) {
61 if (m_map)
62 throw std::runtime_error("ObjComponent::setShape - Cannot change the shape "
63 "of a parameterized object");
64 else
65 m_shape = std::move(newShape);
66}
67
72const Kernel::Material ObjComponent::material() const { return m_shape->material(); }
73
75bool ObjComponent::isValid(const V3D &point) const {
76 // If the form of this component is not defined, just treat as a point
77 if (!shape())
78 return (this->getPos() == point);
79
80 // Otherwise pass through the shifted point to the IObject::isValid method
81 V3D scaleFactor = this->getScaleFactor();
82 return shape()->isValid(factorOutComponentPosition(point) / scaleFactor) != 0;
83}
84
86bool ObjComponent::isOnSide(const V3D &point) const {
87 // If the form of this component is not defined, just treat as a point
88 if (!shape())
89 return (this->getPos() == point);
90 // Otherwise pass through the shifted point to the IObject::isOnSide method
91 V3D scaleFactor = this->getScaleFactor();
92 return shape()->isOnSide(factorOutComponentPosition(point) / scaleFactor) != 0;
93}
94
105 // If the form of this component is not defined, throw NullPointerException
106 if (!shape())
107 throw Kernel::Exception::NullPointerException("ObjComponent::interceptSurface", "shape");
108
109 // TODO: If scaling parameters are ever enabled, would they need need to be
110 // used here?
111 const V3D trkStart = factorOutComponentPosition(track.startPoint());
112 const V3D trkDirection = takeOutRotation(track.direction());
113
114 Track probeTrack(trkStart, trkDirection);
115 const int intercepts = shape()->interceptSurface(probeTrack);
116
117 Track::LType::const_iterator it;
118 for (it = probeTrack.cbegin(); it != probeTrack.cend(); ++it) {
119 V3D in = it->entryPoint;
120 this->getRotation().rotate(in);
121 // use the scale factor
122 in *= getScaleFactor();
123 in += this->getPos();
124 V3D out = it->exitPoint;
125 this->getRotation().rotate(out);
126 // use the scale factor
127 out *= getScaleFactor();
128 out += this->getPos();
129 track.addLink(in, out, out.distance(track.startPoint()), *(this->shape()), this->getComponentID());
130 }
131
132 return intercepts;
133}
134
143 if (m_map) {
144 if (hasComponentInfo()) {
145 return m_map->componentInfo().solidAngle(index(), params);
146 }
147 }
148 // If the form of this component is not defined, throw NullPointerException
149 if (!shape())
150 throw Kernel::Exception::NullPointerException("ObjComponent::solidAngle", "shape");
151 // Otherwise pass through the shifted point to the Object::solidAngle method
152 V3D scaleFactor = this->getScaleFactor();
153 // This is the observer position in the shape's coordinate system.
154 const auto paramsWithFactoredOutComponentPosition =
156 if ((scaleFactor - V3D(1.0, 1.0, 1.0)).norm() < 1e-12)
157 return shape()->solidAngle(paramsWithFactoredOutComponentPosition);
158 else {
159 // This function will scale the object shape when calculating the solid
160 // angle.
161 return shape()->solidAngle(paramsWithFactoredOutComponentPosition, scaleFactor);
162 }
163}
164
179 if (m_map) {
180 if (hasComponentInfo()) {
181 absoluteBB = m_map->componentInfo().boundingBox(index(), &absoluteBB);
182 return;
183 }
184 }
185 // Start with the box in the shape's coordinates
186 const IObject_const_sptr s = shape();
187 if (!s) {
188 absoluteBB.nullify();
189 return;
190 }
191 const BoundingBox &shapeBox = s->getBoundingBox();
192 if (shapeBox.isNull()) {
193 absoluteBB.nullify();
194 return;
195 }
196 std::vector<V3D> Coord_system;
197 if (!absoluteBB.isAxisAligned()) { // copy coordinate system (it is better
198 // then copying the whole BB later)
199 Coord_system.assign(absoluteBB.getCoordSystem().begin(), absoluteBB.getCoordSystem().end());
200 }
201 absoluteBB = BoundingBox(shapeBox);
202 // modify in place for speed
203 V3D scaleFactor = getScaleFactor();
204 // Scale
205 absoluteBB.xMin() *= scaleFactor.X();
206 absoluteBB.xMax() *= scaleFactor.X();
207 absoluteBB.yMin() *= scaleFactor.Y();
208 absoluteBB.yMax() *= scaleFactor.Y();
209 absoluteBB.zMin() *= scaleFactor.Z();
210 absoluteBB.zMax() *= scaleFactor.Z();
211 // Rotate
212 (this->getRotation())
213 .rotateBB(absoluteBB.xMin(), absoluteBB.yMin(), absoluteBB.zMin(), absoluteBB.xMax(), absoluteBB.yMax(),
214 absoluteBB.zMax());
215
216 // Shift
217 const V3D localPos = this->getPos();
218 absoluteBB.xMin() += localPos.X();
219 absoluteBB.xMax() += localPos.X();
220 absoluteBB.yMin() += localPos.Y();
221 absoluteBB.yMax() += localPos.Y();
222 absoluteBB.zMin() += localPos.Z();
223 absoluteBB.zMax() += localPos.Z();
224
225 if (!Coord_system.empty()) {
226 absoluteBB.realign(&Coord_system);
227 }
228}
229
235 const BoundingBox &bbox = shape()->getBoundingBox();
236 return (bbox.yMax() - bbox.yMin()) / getScaleFactor().Y();
237}
238
244 const BoundingBox &bbox = shape()->getBoundingBox();
245 return (bbox.xMax() - bbox.xMin()) / getScaleFactor().X();
246}
247
253 const BoundingBox &bbox = shape()->getBoundingBox();
254 return (bbox.zMax() - bbox.zMin()) / getScaleFactor().Z();
255}
256
263 // If the form of this component is not defined, throw NullPointerException
264 if (!shape())
265 throw Kernel::Exception::NullPointerException("ObjComponent::getPointInObject", "shape");
266 // Call the Object::getPointInObject method, which may give a point in Object
267 // coordinates
268 int result = shape()->getPointInObject(point);
269 // transform point back to component space
270 if (result) {
271 // Scale up
272 V3D scaleFactor = this->getScaleFactor();
273 point *= scaleFactor;
274 Quat Rotate = this->getRotation();
275 Rotate.rotate(point);
276 point += this->getPos();
277 }
278 return result;
279}
280
285 // First subtract the component's position, then undo the rotation
286 return takeOutRotation(point - this->getPos());
287}
288
291 // Get the total rotation of this component and calculate the inverse (reverse
292 // rotation)
293 Quat unRotate = this->getRotation();
294 unRotate.inverse();
295 // Now rotate our point by the angle calculated above
296 unRotate.rotate(point);
297
298 // Can not Consider scaling factor here as this transform used by solidAngle
299 // as well
300 // as IsValid etc. While this would work for latter, breaks former
301
302 return point;
303}
304
309void ObjComponent::draw() const {
310 if (Handle() == nullptr)
311 return;
312 // Render the ObjComponent and then render the object
313 Handle()->render();
314}
315
320 if (shape() != nullptr)
321 shape()->draw();
322}
323
329 if (Handle() == nullptr)
330 return;
331 // Render the ObjComponent and then render the object
332 if (shape() != nullptr)
333 shape()->initDraw();
334 Handle()->initialize();
335}
336
340size_t ObjComponent::registerContents(class ComponentVisitor &componentVisitor) const {
341 if (this->shape() != nullptr && this->shape()->isFiniteGeometry())
342 return componentVisitor.registerGenericObjComponent(*this);
343 else
344 return componentVisitor.registerInfiniteObjComponent(*this);
345}
346
347} // namespace Mantid::Geometry
std::string name
Definition Run.cpp:60
A simple structure that defines an axis-aligned cuboid shaped bounding box for a geometrical object.
Definition BoundingBox.h:33
double xMax() const
Return the maximum value of X.
Definition BoundingBox.h:79
double zMin() const
Return the minimum value of Z.
Definition BoundingBox.h:85
std::vector< Kernel::V3D > const & getCoordSystem() const
returns the coordinate system to which BB is alighned to;
bool isNull() const
Is this a default constructed box?
double zMax() const
Return the maximum value of Z.
Definition BoundingBox.h:87
double yMax() const
Return the maximum value of Y.
Definition BoundingBox.h:83
bool isAxisAligned() const
Check if it is normal axis aligned bounding box or not.
double xMin() const
Return the minimum value of X.
Definition BoundingBox.h:77
void nullify()
set BB in to undefined state with min=FLT_MAX>max=-FLT_MAX
double yMin() const
Return the minimum value of Y.
Definition BoundingBox.h:81
void realign(std::vector< Kernel::V3D > const *const pCS=nullptr)
reallign the BB according to new coordinate system, provided earlier or specified as parameter;
double solidAngle(const size_t componentIndex, const Geometry::SolidAngleParams &params) const
BoundingBox boundingBox(const size_t componentIndex, const BoundingBox *reference=nullptr, const bool excludeMonitors=false) const
Compute the bounding box for the component with componentIndex taking into account all sub components...
ComponentVisitor : Visitor for IComponents.
virtual size_t registerGenericObjComponent(const IObjComponent &objComponent)=0
virtual size_t registerInfiniteObjComponent(const IObjComponent &component)=0
Component is a wrapper for a Component which can modify some of its parameters, e....
Definition Component.h:42
const ParameterMap * m_map
A pointer to const ParameterMap containing the parameters.
Definition Component.h:316
size_t index() const
Helper for legacy access mode. Returns the index of the component.
const IComponent * base() const
Returns the address of the base component.
Definition Component.h:289
Kernel::V3D getScaleFactor() const override
Returns the ScaleFactor.
Kernel::V3D getPos() const override
Get the position of the IComponent. Tree structure is traverse through the.
const Component * m_base
The base component - this is the unmodified component (without the parameters).
Definition Component.h:314
Kernel::Quat getRotation() const override
Get the absolute orientation of the IComponent.
void render() const
Render Object or ObjComponent.
void initialize() const
Prepare/Initialize Object/ObjComponent to be rendered.
base class for Geometric IComponent
Definition IComponent.h:53
Object Component class, this class brings together the physical attributes of the component to the po...
GeometryHandler * Handle() const
Gets the GeometryHandler.
Object Component class, this class brings together the physical attributes of the component to the po...
double solidAngle(const Geometry::SolidAngleParams &params) const override
Finds the approximate solid angle covered by the component when viewed from the point given.
int interceptSurface(Track &track) const override
Checks whether the track given will pass through this Component.
ObjComponent(const IComponent *base, const ParameterMap *map)
Constructor for parametrized component.
void drawObject() const override
Draws the Object.
bool isValid(const Kernel::V3D &point) const override
Does the point given lie within this object component?
int getPointInObject(Kernel::V3D &point) const override
Try to find a point that lies within (or on) the object.
std::shared_ptr< const IObject > m_shape
The physical geometry representation.
void draw() const override
Draws the objcomponent, If the handler is not set then this function does nothing.
void getBoundingBox(BoundingBox &absoluteBB) const override
get bounding box, which may or may not be axis aligned;
const std::shared_ptr< const IObject > shape() const override
Return the shape of the component.
virtual double getWidth() const
get Width (X-dimension) value for component
const Kernel::V3D factorOutComponentPosition(const Kernel::V3D &point) const
Find the point that's in the same place relative to the constituent geometrical Object if the positio...
const Kernel::V3D takeOutRotation(Kernel::V3D point) const
Rotates a point by the reverse of the component's rotation.
bool isOnSide(const Kernel::V3D &point) const override
Does the point given lie on the surface of this object component?
virtual size_t registerContents(class ComponentVisitor &componentVisitor) const override
Register the contents of this ObjComponent.
void setShape(std::shared_ptr< const IObject > newShape)
Set a new shape on the component void setShape(std::shared_ptr<const IObject> newShape);.
virtual double getHeight() const
get Height (Y-dimension) value for component
void initDraw() const override
Initializes the ObjComponent for rendering, this function should be called before rendering.
virtual double getDepth() const
get Depth (Z-dimension) value for component
const Kernel::Material material() const override
Return the material this component is made from.
const Geometry::ComponentInfo & componentInfo() const
Only for use by ExperimentInfo. Returns a reference to the ComponentInfo.
const SolidAngleParams copyWithNewObserver(Kernel::V3D newObserver) const
const Kernel::V3D & observer() const
Defines a track as a start point and a direction.
Definition Track.h:165
const Kernel::V3D & startPoint() const
Returns the starting point.
Definition Track.h:191
int addLink(const Kernel::V3D &firstPoint, const Kernel::V3D &secondPoint, const double distanceAlongTrack, const IObject &obj, const ComponentID compID=nullptr)
Adds a link to the track.
Definition Track.cpp:152
const Kernel::V3D & direction() const
Returns the direction as a unit vector.
Definition Track.h:193
LType::const_iterator cbegin() const
Returns an interator to the start of the set of links (const version)
Definition Track.h:206
LType::const_iterator cend() const
Returns an interator to one-past-the-end of the set of links (const version)
Definition Track.h:209
Exception thrown when an attempt is made to dereference a null pointer.
Definition Exception.h:305
A material is defined as being composed of a given element, defined as a PhysicalConstants::NeutronAt...
Definition Material.h:50
Class for quaternions.
Definition Quat.h:39
void inverse()
Inverse a quaternion (in the sense of rotation inversion)
Definition Quat.cpp:376
void rotate(V3D &) const
Rotate a vector.
Definition Quat.cpp:397
Class for 3D vectors.
Definition V3D.h:34
double distance(const V3D &v) const noexcept
Calculates the distance between two vectors.
Definition V3D.h:293
constexpr double X() const noexcept
Get x.
Definition V3D.h:238
constexpr double Y() const noexcept
Get y.
Definition V3D.h:239
constexpr double Z() const noexcept
Get z.
Definition V3D.h:240
std::shared_ptr< const IObject > IObject_const_sptr
Typdef for a shared pointer to a const object.
Definition IObject.h:95
STL namespace.