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
142double ObjComponent::solidAngle(const V3D &observer) const {
143 if (m_map) {
144 if (hasComponentInfo()) {
145 return m_map->componentInfo().solidAngle(index(), observer);
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 if ((scaleFactor - V3D(1.0, 1.0, 1.0)).norm() < 1e-12)
154 return shape()->solidAngle(factorOutComponentPosition(observer));
155 else {
156 // This is the observer position in the shape's coordinate system.
157 V3D relativeObserver = factorOutComponentPosition(observer);
158 // This function will scale the object shape when calculating the solid
159 // angle.
160 return shape()->solidAngle(relativeObserver, scaleFactor);
161 }
162}
163
178 if (m_map) {
179 if (hasComponentInfo()) {
180 absoluteBB = m_map->componentInfo().boundingBox(index(), &absoluteBB);
181 return;
182 }
183 }
184 // Start with the box in the shape's coordinates
185 const IObject_const_sptr s = shape();
186 if (!s) {
187 absoluteBB.nullify();
188 return;
189 }
190 const BoundingBox &shapeBox = s->getBoundingBox();
191 if (shapeBox.isNull()) {
192 absoluteBB.nullify();
193 return;
194 }
195 std::vector<V3D> Coord_system;
196 if (!absoluteBB.isAxisAligned()) { // copy coordinate system (it is better
197 // then copying the whole BB later)
198 Coord_system.assign(absoluteBB.getCoordSystem().begin(), absoluteBB.getCoordSystem().end());
199 }
200 absoluteBB = BoundingBox(shapeBox);
201 // modify in place for speed
202 V3D scaleFactor = getScaleFactor();
203 // Scale
204 absoluteBB.xMin() *= scaleFactor.X();
205 absoluteBB.xMax() *= scaleFactor.X();
206 absoluteBB.yMin() *= scaleFactor.Y();
207 absoluteBB.yMax() *= scaleFactor.Y();
208 absoluteBB.zMin() *= scaleFactor.Z();
209 absoluteBB.zMax() *= scaleFactor.Z();
210 // Rotate
211 (this->getRotation())
212 .rotateBB(absoluteBB.xMin(), absoluteBB.yMin(), absoluteBB.zMin(), absoluteBB.xMax(), absoluteBB.yMax(),
213 absoluteBB.zMax());
214
215 // Shift
216 const V3D localPos = this->getPos();
217 absoluteBB.xMin() += localPos.X();
218 absoluteBB.xMax() += localPos.X();
219 absoluteBB.yMin() += localPos.Y();
220 absoluteBB.yMax() += localPos.Y();
221 absoluteBB.zMin() += localPos.Z();
222 absoluteBB.zMax() += localPos.Z();
223
224 if (!Coord_system.empty()) {
225 absoluteBB.realign(&Coord_system);
226 }
227}
228
234 const BoundingBox &bbox = shape()->getBoundingBox();
235 return (bbox.yMax() - bbox.yMin()) / getScaleFactor().Y();
236}
237
243 const BoundingBox &bbox = shape()->getBoundingBox();
244 return (bbox.xMax() - bbox.xMin()) / getScaleFactor().X();
245}
246
252 const BoundingBox &bbox = shape()->getBoundingBox();
253 return (bbox.zMax() - bbox.zMin()) / getScaleFactor().Z();
254}
255
262 // If the form of this component is not defined, throw NullPointerException
263 if (!shape())
264 throw Kernel::Exception::NullPointerException("ObjComponent::getPointInObject", "shape");
265 // Call the Object::getPointInObject method, which may give a point in Object
266 // coordinates
267 int result = shape()->getPointInObject(point);
268 // transform point back to component space
269 if (result) {
270 // Scale up
271 V3D scaleFactor = this->getScaleFactor();
272 point *= scaleFactor;
273 Quat Rotate = this->getRotation();
274 Rotate.rotate(point);
275 point += this->getPos();
276 }
277 return result;
278}
279
284 // First subtract the component's position, then undo the rotation
285 return takeOutRotation(point - this->getPos());
286}
287
290 // Get the total rotation of this component and calculate the inverse (reverse
291 // rotation)
292 Quat unRotate = this->getRotation();
293 unRotate.inverse();
294 // Now rotate our point by the angle calculated above
295 unRotate.rotate(point);
296
297 // Can not Consider scaling factor here as this transform used by solidAngle
298 // as well
299 // as IsValid etc. While this would work for latter, breaks former
300
301 return point;
302}
303
308void ObjComponent::draw() const {
309 if (Handle() == nullptr)
310 return;
311 // Render the ObjComponent and then render the object
312 Handle()->render();
313}
314
319 if (shape() != nullptr)
320 shape()->draw();
321}
322
328 if (Handle() == nullptr)
329 return;
330 // Render the ObjComponent and then render the object
331 if (shape() != nullptr)
332 shape()->initDraw();
333 Handle()->initialize();
334}
335
339size_t ObjComponent::registerContents(class ComponentVisitor &componentVisitor) const {
340 if (this->shape() != nullptr && this->shape()->isFiniteGeometry())
341 return componentVisitor.registerGenericObjComponent(*this);
342 else
343 return componentVisitor.registerInfiniteObjComponent(*this);
344}
345
346} // namespace Mantid::Geometry
A simple structure that defines an axis-aligned cuboid shaped bounding box for a geometrical object.
Definition: BoundingBox.h:34
double xMax() const
Return the maximum value of X.
Definition: BoundingBox.h:80
double zMin() const
Return the minimum value of Z.
Definition: BoundingBox.h:86
std::vector< Kernel::V3D > const & getCoordSystem() const
returns the coordinate system to which BB is alighned to;
Definition: BoundingBox.h:118
bool isNull() const
Is this a default constructed box?
Definition: BoundingBox.h:104
double zMax() const
Return the maximum value of Z.
Definition: BoundingBox.h:88
double yMax() const
Return the maximum value of Y.
Definition: BoundingBox.h:84
bool isAxisAligned() const
Check if it is normal axis aligned bounding box or not.
Definition: BoundingBox.h:116
double xMin() const
Return the minimum value of X.
Definition: BoundingBox.h:78
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:82
void realign(std::vector< Kernel::V3D > const *const pCS=nullptr)
reallign the BB according to new coordinate system, provided earlier or specified as parameter;
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...
double solidAngle(const size_t componentIndex, const Kernel::V3D &observer) const
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:41
const ParameterMap * m_map
A pointer to const ParameterMap containing the parameters.
Definition: Component.h:307
size_t index() const
Helper for legacy access mode. Returns the index of the component.
Definition: Component.cpp:297
const IComponent * base() const
Returns the address of the base component.
Definition: Component.h:280
Kernel::V3D getScaleFactor() const override
Returns the ScaleFactor.
Definition: Component.cpp:282
Kernel::V3D getPos() const override
Get the position of the IComponent. Tree structure is traverse through the.
Definition: Component.cpp:325
const Component * m_base
The base component - this is the unmodified component (without the parameters).
Definition: Component.h:305
Kernel::Quat getRotation() const override
Get the absolute orientation of the IComponent.
Definition: Component.cpp:387
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:51
Object Component class, this class brings together the physical attributes of the component to the po...
Definition: IObjComponent.h:37
GeometryHandler * Handle() const
Gets the GeometryHandler.
Definition: IObjComponent.h:92
Object Component class, this class brings together the physical attributes of the component to the po...
Definition: ObjComponent.h:33
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.
double solidAngle(const Kernel::V3D &observer) const override
Finds the approximate solid angle covered by the component when viewed from the point given.
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.
Definition: ObjComponent.h:86
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.
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:287
constexpr double X() const noexcept
Get x.
Definition: V3D.h:232
constexpr double Y() const noexcept
Get y.
Definition: V3D.h:233
constexpr double Z() const noexcept
Get z.
Definition: V3D.h:234
std::shared_ptr< const IObject > IObject_const_sptr
Typdef for a shared pointer to a const object.
Definition: IObject.h:94
STL namespace.