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
73 auto const objectShape = shape();
74 return objectShape ? objectShape->material() : Kernel::Material();
75}
76
78bool ObjComponent::isValid(const V3D &point) const {
79 // If the form of this component is not defined, just treat as a point
80 if (!shape())
81 return (this->getPos() == point);
82
83 // Otherwise pass through the shifted point to the IObject::isValid method
84 V3D scaleFactor = this->getScaleFactor();
85 return shape()->isValid(factorOutComponentPosition(point) / scaleFactor) != 0;
86}
87
89bool ObjComponent::isOnSide(const V3D &point) const {
90 // If the form of this component is not defined, just treat as a point
91 if (!shape())
92 return (this->getPos() == point);
93 // Otherwise pass through the shifted point to the IObject::isOnSide method
94 V3D scaleFactor = this->getScaleFactor();
95 return shape()->isOnSide(factorOutComponentPosition(point) / scaleFactor) != 0;
96}
97
108 // If the form of this component is not defined, throw NullPointerException
109 if (!shape())
110 throw Kernel::Exception::NullPointerException("ObjComponent::interceptSurface", "shape");
111
112 // TODO: If scaling parameters are ever enabled, would they need need to be
113 // used here?
114 const V3D trkStart = factorOutComponentPosition(track.startPoint());
115 const V3D trkDirection = takeOutRotation(track.direction());
116
117 Track probeTrack(trkStart, trkDirection);
118 const int intercepts = shape()->interceptSurface(probeTrack);
119
120 Track::LType::const_iterator it;
121 for (it = probeTrack.cbegin(); it != probeTrack.cend(); ++it) {
122 V3D in = it->entryPoint;
123 this->getRotation().rotate(in);
124 // use the scale factor
125 in *= getScaleFactor();
126 in += this->getPos();
127 V3D out = it->exitPoint;
128 this->getRotation().rotate(out);
129 // use the scale factor
130 out *= getScaleFactor();
131 out += this->getPos();
132 track.addLink(in, out, out.distance(track.startPoint()), *(this->shape()), this->getComponentID());
133 }
134
135 return intercepts;
136}
137
146 if (m_map) {
147 if (hasComponentInfo()) {
148 return m_map->componentInfo().solidAngle(index(), params);
149 }
150 }
151 // If the form of this component is not defined, throw NullPointerException
152 if (!shape())
153 throw Kernel::Exception::NullPointerException("ObjComponent::solidAngle", "shape");
154 // Otherwise pass through the shifted point to the Object::solidAngle method
155 V3D scaleFactor = this->getScaleFactor();
156 // This is the observer position in the shape's coordinate system.
157 const auto paramsWithFactoredOutComponentPosition =
159 if ((scaleFactor - V3D(1.0, 1.0, 1.0)).norm() < 1e-12)
160 return shape()->solidAngle(paramsWithFactoredOutComponentPosition);
161 else {
162 // This function will scale the object shape when calculating the solid
163 // angle.
164 return shape()->solidAngle(paramsWithFactoredOutComponentPosition, scaleFactor);
165 }
166}
167
182 if (m_map) {
183 if (hasComponentInfo()) {
184 absoluteBB = m_map->componentInfo().boundingBox(index(), &absoluteBB);
185 return;
186 }
187 }
188 // Start with the box in the shape's coordinates
189 const IObject_const_sptr s = shape();
190 if (!s) {
191 absoluteBB.nullify();
192 return;
193 }
194 const BoundingBox &shapeBox = s->getBoundingBox();
195 if (shapeBox.isNull()) {
196 absoluteBB.nullify();
197 return;
198 }
199 std::vector<V3D> Coord_system;
200 if (!absoluteBB.isAxisAligned()) { // copy coordinate system (it is better
201 // then copying the whole BB later)
202 Coord_system.assign(absoluteBB.getCoordSystem().begin(), absoluteBB.getCoordSystem().end());
203 }
204 absoluteBB = BoundingBox(shapeBox);
205 // modify in place for speed
206 V3D scaleFactor = getScaleFactor();
207 // Scale
208 absoluteBB.xMin() *= scaleFactor.X();
209 absoluteBB.xMax() *= scaleFactor.X();
210 absoluteBB.yMin() *= scaleFactor.Y();
211 absoluteBB.yMax() *= scaleFactor.Y();
212 absoluteBB.zMin() *= scaleFactor.Z();
213 absoluteBB.zMax() *= scaleFactor.Z();
214 // Rotate
215 (this->getRotation())
216 .rotateBB(absoluteBB.xMin(), absoluteBB.yMin(), absoluteBB.zMin(), absoluteBB.xMax(), absoluteBB.yMax(),
217 absoluteBB.zMax());
218
219 // Shift
220 const V3D localPos = this->getPos();
221 absoluteBB.xMin() += localPos.X();
222 absoluteBB.xMax() += localPos.X();
223 absoluteBB.yMin() += localPos.Y();
224 absoluteBB.yMax() += localPos.Y();
225 absoluteBB.zMin() += localPos.Z();
226 absoluteBB.zMax() += localPos.Z();
227
228 if (!Coord_system.empty()) {
229 absoluteBB.realign(&Coord_system);
230 }
231}
232
238 const BoundingBox &bbox = shape()->getBoundingBox();
239 return (bbox.yMax() - bbox.yMin()) / getScaleFactor().Y();
240}
241
247 const BoundingBox &bbox = shape()->getBoundingBox();
248 return (bbox.xMax() - bbox.xMin()) / getScaleFactor().X();
249}
250
256 const BoundingBox &bbox = shape()->getBoundingBox();
257 return (bbox.zMax() - bbox.zMin()) / getScaleFactor().Z();
258}
259
266 // If the form of this component is not defined, throw NullPointerException
267 if (!shape())
268 throw Kernel::Exception::NullPointerException("ObjComponent::getPointInObject", "shape");
269 // Call the Object::getPointInObject method, which may give a point in Object
270 // coordinates
271 int result = shape()->getPointInObject(point);
272 // transform point back to component space
273 if (result) {
274 // Scale up
275 V3D scaleFactor = this->getScaleFactor();
276 point *= scaleFactor;
277 Quat Rotate = this->getRotation();
278 Rotate.rotate(point);
279 point += this->getPos();
280 }
281 return result;
282}
283
288 // First subtract the component's position, then undo the rotation
289 return takeOutRotation(point - this->getPos());
290}
291
294 // Get the total rotation of this component and calculate the inverse (reverse
295 // rotation)
296 Quat unRotate = this->getRotation();
297 unRotate.inverse();
298 // Now rotate our point by the angle calculated above
299 unRotate.rotate(point);
300
301 // Can not Consider scaling factor here as this transform used by solidAngle
302 // as well
303 // as IsValid etc. While this would work for latter, breaks former
304
305 return point;
306}
307
312void ObjComponent::draw() const {
313 if (Handle() == nullptr)
314 return;
315 // Render the ObjComponent and then render the object
316 Handle()->render();
317}
318
323 if (shape() != nullptr)
324 shape()->draw();
325}
326
332 if (Handle() == nullptr)
333 return;
334 // Render the ObjComponent and then render the object
335 if (shape() != nullptr)
336 shape()->initDraw();
337 Handle()->initialize();
338}
339
343size_t ObjComponent::registerContents(class ComponentVisitor &componentVisitor) const {
344 if (this->shape() != nullptr && this->shape()->isFiniteGeometry())
345 return componentVisitor.registerGenericObjComponent(*this);
346 else
347 return componentVisitor.registerInfiniteObjComponent(*this);
348}
349
350} // 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:318
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:291
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:316
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.
Parameter map iterator typedef.
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:38
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:35
double distance(const V3D &v) const noexcept
Calculates the distance between two vectors.
Definition V3D.h:294
constexpr double X() const noexcept
Get x.
Definition V3D.h:239
constexpr double Y() const noexcept
Get y.
Definition V3D.h:240
constexpr double Z() const noexcept
Get z.
Definition V3D.h:241
std::shared_ptr< const IObject > IObject_const_sptr
Typdef for a shared pointer to a const object.
Definition IObject.h:108
STL namespace.