Commit 81c5b9af authored by Roman Tolchenov's avatar Roman Tolchenov
Browse files

ShapeFactory returns IObject. Re #12827

parent 12593ae3
......@@ -3,6 +3,7 @@
//--------------------------------
#include "MantidDataHandling/CreateSampleShape.h"
#include "MantidGeometry/Objects/ShapeFactory.h"
#include "MantidGeometry/Objects/CSGObject.h"
#include "MantidAPI/MatrixWorkspace.h"
#include "MantidKernel/Material.h"
#include "MantidAPI/Sample.h"
......@@ -46,11 +47,14 @@ void CreateSampleShape::exec() {
if (shape->hasValidShape()) {
const auto mat = workspace->sample().getMaterial();
shape->setMaterial(mat);
workspace->mutableSample().setShape(*shape);
workspace->mutableSample().setShape(shape);
} else {
std::ostringstream msg;
msg << "Object has invalid shape. TopRule = " << shape->topRule()
<< ", number of surfaces = " << shape->getSurfacePtr().size() << "\n";
msg << "Object has invalid shape.";
if (auto csgShape = dynamic_cast<Geometry::CSGObject*>(shape.get())) {
msg << " TopRule = " << csgShape->topRule()
<< ", number of surfaces = " << csgShape->getSurfacePtr().size() << "\n";
}
throw std::runtime_error(msg.str());
}
// Done!
......
......@@ -33,7 +33,7 @@ void DefineGaugeVolume::exec() {
// Get the XML definition
const std::string shapeXML = getProperty("ShapeXML");
// Try creating the shape to make sure the input's valid
boost::shared_ptr<Geometry::CSGObject> shape_sptr =
auto shape_sptr =
Geometry::ShapeFactory().createShape(shapeXML);
if (!shape_sptr->hasValidShape()) {
g_log.error("Invalid shape definition provided. Gauge Volume NOT added to "
......
......@@ -168,7 +168,7 @@ void LoadQKK::exec() {
pixel_width_str + "\" y= \"" + pixel_height_str + "\" z=\"0\" />"
"</cuboid>";
// Create a shape object which will be shared by all pixels.
Geometry::Object_sptr shape = Geometry::ShapeFactory().createShape(detXML);
auto shape = Geometry::ShapeFactory().createShape(detXML);
// Initialise the detector specifying the sizes.
bank->initialize(shape, int(nx), 0, pixel_width, int(ny), 0, pixel_height, 1,
true, int(nx));
......
......@@ -62,7 +62,7 @@ public:
sampleShape->setID("mysample");
Material alum("Al", getNeutronAtom(13), 2.6989);
sampleShape->setMaterial(alum);
inputWS->mutableSample().setShape(*sampleShape);
inputWS->mutableSample().setShape(sampleShape);
CreateSampleShape alg;
alg.initialize();
......@@ -100,7 +100,7 @@ public:
Mantid::API::AnalysisDataService::Instance().retrieve(
"TestWorkspace"));
const Mantid::Geometry::CSGObject &sample = ws->sample().getShape();
auto &sample = ws->sample().getShape();
Mantid::Kernel::V3D point(x, y, z);
if (inside) {
......
......@@ -90,7 +90,7 @@ public:
auto inputWS = WorkspaceCreationHelper::create2DWorkspaceBinned(1, 1);
auto sampleShape = ComponentCreationHelper::createSphere(0.5);
sampleShape->setID("mysample");
inputWS->mutableSample().setShape(*sampleShape);
inputWS->mutableSample().setShape(sampleShape);
auto alg = createAlgorithm(inputWS);
alg->setProperty("Material", createMaterialProps());
......@@ -113,7 +113,7 @@ public:
sampleShape->setID("mysample");
Material alum("Al", getNeutronAtom(13), 2.6989);
sampleShape->setMaterial(alum);
inputWS->mutableSample().setShape(*sampleShape);
inputWS->mutableSample().setShape(sampleShape);
auto alg = createAlgorithm(inputWS);
alg->setProperty("Geometry", createGenericGeometryProps());
......@@ -121,7 +121,8 @@ public:
TS_ASSERT(alg->isExecuted());
// New shape
TS_ASSERT_DELTA(0.02, getSphereRadius(inputWS->sample().getShape()), 1e-08);
auto &sphere = dynamic_cast<const Mantid::Geometry::CSGObject&>(inputWS->sample().getShape());
TS_ASSERT_DELTA(0.02, getSphereRadius(sphere), 1e-08);
// Old material
const auto &material = inputWS->sample().getMaterial();
TS_ASSERT_EQUALS("Al", material.name());
......@@ -192,7 +193,7 @@ public:
// New shape
// radius was 0.1 in <samplegeometry> set in constructor now 0.4
// from createOverrideGeometryProps
TS_ASSERT_DELTA(0.4, getSphereRadius(sampleShape), 1e-08);
TS_ASSERT_DELTA(0.4, getSphereRadius(dynamic_cast<const Mantid::Geometry::CSGObject&>(sampleShape)), 1e-08);
}
void test_Setting_Geometry_As_FlatPlate() {
......
......@@ -231,7 +231,7 @@ public:
TS_ASSERT_EQUALS(sampleVal->isValid(ws),
"The sample is missing the following properties: shape");
auto shape = ComponentCreationHelper::createSphere(0.01);
ws->mutableSample().setShape(*shape);
ws->mutableSample().setShape(shape);
TS_ASSERT_EQUALS(sampleVal->isValid(ws), "");
}
......@@ -245,7 +245,7 @@ public:
"The sample is missing the following properties: material");
auto noShape = boost::make_shared<CSGObject>();
noShape->setMaterial(Material("V", NeutronAtom(), 0.072));
ws->mutableSample().setShape(*noShape);
ws->mutableSample().setShape(noShape);
TS_ASSERT_EQUALS(sampleVal->isValid(ws), "");
}
......@@ -259,7 +259,7 @@ public:
"The sample is missing the following properties: shape,material");
auto shape = ComponentCreationHelper::createSphere(0.01);
shape->setMaterial(Material("V", NeutronAtom(), 0.072));
ws->mutableSample().setShape(*shape);
ws->mutableSample().setShape(shape);
TS_ASSERT_EQUALS(sampleVal->isValid(ws), "");
}
}
......
......@@ -2,7 +2,9 @@
#define MANTID_GEOMETRY_CONTAINER_H_
#include "MantidGeometry/DllConfig.h"
#include "MantidGeometry/Objects/CSGObject.h"
#include "MantidGeometry/Objects/IObject.h"
#include "MantidKernel/Material.h"
#include "MantidKernel/V3D.h"
#include <unordered_map>
namespace Mantid {
......@@ -35,11 +37,13 @@ namespace Geometry {
File change history is stored at: <https://github.com/mantidproject/mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class MANTID_GEOMETRY_DLL Container final : public CSGObject {
class MANTID_GEOMETRY_DLL Container final : public IObject {
public:
typedef std::unordered_map<std::string, double> ShapeArgs;
Container() = default;
Container();
Container(IObject_sptr shape);
Container(const Container& container);
Container(std::string xml);
bool hasSampleShape() const;
......@@ -47,7 +51,51 @@ public:
void setSampleShape(const std::string &sampleShapeXML);
bool isValid(const Kernel::V3D &p) const override {return m_shape->isValid(p); }
bool isOnSide(const Kernel::V3D &p) const override {return m_shape->isOnSide(p);}
int calcValidType(const Kernel::V3D &Pt, const Kernel::V3D &uVec) const override {return m_shape->calcValidType(Pt, uVec);}
bool hasValidShape() const override {return m_shape->hasValidShape();}
int setObject(const int ON, const std::string &Ln) override {return m_shape->setObject(ON, Ln);}
int populate(const std::map<int, boost::shared_ptr<Surface>> &m) override {return m_shape->populate(m);}
IObject* clone() const override {return new Container(*this);}
int getName() const override {return m_shape->getName(); }
void setName(const int nx) override {m_shape->setName(nx); }
int interceptSurface(Geometry::Track &t) const override {return m_shape->interceptSurface(t); }
double solidAngle(const Kernel::V3D &observer) const override {return m_shape->solidAngle(observer);}
double solidAngle(const Kernel::V3D &observer,
const Kernel::V3D &scaleFactor) const override {return m_shape->solidAngle(observer, scaleFactor); }
double volume() const override {return m_shape->volume();}
const BoundingBox &getBoundingBox() const override {return m_shape->getBoundingBox(); }
int getPointInObject(Kernel::V3D &point) const override {return m_shape->getPointInObject(point); }
Kernel::V3D generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
const size_t i) const override {return m_shape->generatePointInObject(rng, i); }
Kernel::V3D generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
const BoundingBox &activeRegion,
const size_t i) const override {return m_shape->generatePointInObject(rng, activeRegion, i); }
void GetObjectGeom(int &type, std::vector<Kernel::V3D> &vectors,
double &myradius, double &myheight) const override {m_shape->GetObjectGeom(type, vectors, myradius, myheight); }
boost::shared_ptr<GeometryHandler> getGeometryHandler() override {return m_shape->getGeometryHandler(); }
std::string getShapeXML() const override {return m_shape->getShapeXML(); }
void draw() const override {m_shape->draw();}
void initDraw() const override {m_shape->initDraw();}
void
setVtkGeometryCacheReader(boost::shared_ptr<vtkGeometryCacheReader> reader) override {m_shape->setVtkGeometryCacheReader(reader);}
void
setVtkGeometryCacheWriter(boost::shared_ptr<vtkGeometryCacheWriter> writer) override {m_shape->setVtkGeometryCacheWriter(writer);}
void setMaterial(const Kernel::Material &material) override {m_shape->setMaterial(material); }
const Kernel::Material material() const override {return m_shape->material(); }
void setID(const std::string &id) override {m_shape->setID(id); }
const std::string &id() const override {return m_shape->id(); }
private:
IObject_sptr m_shape;
std::string m_sampleShapeXML;
};
......
......@@ -66,12 +66,12 @@ public:
bool isValid(const Kernel::V3D &point) const;
int interceptSurfaces(Track &track) const;
void add(const Object_const_sptr &component);
void add(const IObject_const_sptr &component);
private:
std::string m_name;
// Element zero is always assumed to be the can
std::vector<Object_const_sptr> m_components;
std::vector<IObject_const_sptr> m_components;
};
// Typedef a unique_ptr
......
......@@ -43,7 +43,7 @@ class MANTID_GEOMETRY_DLL SampleEnvironmentSpec {
public:
// Convenience typedefs
using ContainerIndex = std::unordered_map<std::string, Container_const_sptr>;
using ComponentList = std::vector<Object_const_sptr>;
using ComponentList = std::vector<IObject_const_sptr>;
SampleEnvironmentSpec(std::string name);
......@@ -58,7 +58,7 @@ public:
SampleEnvironment_uptr buildEnvironment(const std::string &canID) const;
void addContainer(const Container_const_sptr &can);
void addComponent(const Object_const_sptr &component);
void addComponent(const IObject_const_sptr &component);
private:
std::string m_name;
......
......@@ -62,8 +62,7 @@ private:
void parseAndAddContainers(SampleEnvironmentSpec *spec,
Poco::XML::Element *element) const;
Container_const_sptr parseContainer(Poco::XML::Element *element) const;
template <typename ObjectType>
boost::shared_ptr<ObjectType>
boost::shared_ptr<IObject>
parseComponent(Poco::XML::Element *element) const;
// Members
......
......@@ -79,8 +79,8 @@ public:
/// Return the top rule
const Rule *topRule() const { return TopRule.get(); }
void setID(const std::string &id) { m_id = id; }
inline const std::string &id() const { return m_id; }
void setID(const std::string &id) override { m_id = id; }
const std::string &id() const override { return m_id; }
void setName(const int nx) override { ObjNum = nx; } ///< Set Name
int getName() const override { return ObjNum; } ///< Get Name
......@@ -113,7 +113,7 @@ public:
bool isValid(const std::map<int, int> &)
const; ///< Check if a set of surfaces are valid.
bool isOnSide(const Kernel::V3D &) const override;
int calcValidType(const Kernel::V3D &Pt, const Kernel::V3D &uVec) const;
int calcValidType(const Kernel::V3D &Pt, const Kernel::V3D &uVec) const override;
std::vector<int> getSurfaceIndex() const;
/// Get the list of surfaces (const version)
......@@ -146,7 +146,7 @@ public:
double rayTraceSolidAngle(const Kernel::V3D &observer) const;
/// Calculates the volume of this object.
double volume() const;
double volume() const override;
/// Calculate (or return cached value of) Axis Aligned Bounding box
/// (DEPRECATED)
......
......@@ -56,6 +56,7 @@ class MANTID_GEOMETRY_DLL IObject {
public:
virtual bool isValid(const Kernel::V3D &) const = 0;
virtual bool isOnSide(const Kernel::V3D &) const = 0;
virtual int calcValidType(const Kernel::V3D &Pt, const Kernel::V3D &uVec) const = 0;
virtual bool hasValidShape() const = 0;
virtual int setObject(const int ON, const std::string &Ln) = 0;
virtual int populate(const std::map<int, boost::shared_ptr<Surface>> &) = 0;
......@@ -72,8 +73,11 @@ public:
const Kernel::V3D &scaleFactor) const = 0;
/// Return cached value of axis-aligned bounding box
virtual const BoundingBox &getBoundingBox() const = 0;
virtual double volume() const = 0;
virtual int getPointInObject(Kernel::V3D &point) const = 0;
virtual Kernel::V3D generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
const size_t) const = 0;
virtual Kernel::V3D generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
const BoundingBox &activeRegion,
const size_t) const = 0;
......@@ -96,6 +100,8 @@ public:
virtual void setMaterial(const Kernel::Material &material) = 0;
virtual const Kernel::Material material() const = 0;
virtual void setID(const std::string &id) = 0;
virtual const std::string &id() const = 0;
};
/// Typdef for a shared pointer
......
......@@ -84,10 +84,8 @@ File change history is stored at: <https://github.com/mantidproject/mantid>
*/
class MANTID_GEOMETRY_DLL ShapeFactory {
public:
template <typename ObjectType = IObject>
boost::shared_ptr<ObjectType> createShape(Poco::XML::Element *pElem);
template <typename ObjectType = IObject>
boost::shared_ptr<ObjectType> createShape(std::string shapeXML,
boost::shared_ptr<IObject> createShape(Poco::XML::Element *pElem);
boost::shared_ptr<IObject> createShape(std::string shapeXML,
bool addTypeTag = true);
boost::shared_ptr<IObject> createHexahedralShape(double xlb, double xlf,
......
#include "MantidGeometry/Instrument/Container.h"
#include "MantidGeometry/Objects/ShapeFactory.h"
#include "MantidGeometry/Objects/CSGObject.h"
#include "Poco/DOM/AutoPtr.h"
#include "Poco/DOM/DOMParser.h"
......@@ -8,6 +9,7 @@
#include "Poco/DOM/NodeFilter.h"
#include "Poco/SAX/InputSource.h"
#include "Poco/SAX/SAXException.h"
#include <boost/make_shared.hpp>
namespace Mantid {
namespace Geometry {
......@@ -45,11 +47,20 @@ void updateTreeValues(Poco::XML::Element *root,
//------------------------------------------------------------------------------
// Public methods
//------------------------------------------------------------------------------
Container::Container() : m_shape(boost::make_shared<CSGObject>()) {
}
Container::Container(IObject_sptr shape) : m_shape(shape) {
}
Container::Container(const Container& container) :
m_shape(IObject_sptr(container.m_shape->clone())), m_sampleShapeXML(container.m_sampleShapeXML) {}
/**
* Construct a container providing an XML definition shape
* @param xml Definition of the shape in xml
*/
Container::Container(std::string xml) : CSGObject(xml) {}
Container::Container(std::string xml) : m_shape(boost::make_shared<CSGObject>(xml)) {}
/**
* @return True if the can contains a defintion of the sample shape
......@@ -87,7 +98,7 @@ Container::createSampleShape(const Container::ShapeArgs &args) const {
updateTreeValues(root, args);
ShapeFactory factory;
return factory.createShape<CSGObject>(root);
return factory.createShape(root);
}
/**
......@@ -110,9 +121,5 @@ void Container::setSampleShape(const std::string &sampleShapeXML) {
m_sampleShapeXML = sampleShapeXML;
}
//------------------------------------------------------------------------------
// Private methods
//------------------------------------------------------------------------------
} // namespace Geometry
} // namespace Mantid
......@@ -3,7 +3,6 @@
//------------------------------------------------------------------------------
#include "MantidGeometry/Instrument/SampleEnvironment.h"
#include "MantidGeometry/IObjComponent.h"
#include "MantidGeometry/Objects/CSGObject.h"
#include "MantidGeometry/Objects/Track.h"
#include "MantidKernel/PseudoRandomNumberGenerator.h"
......@@ -103,7 +102,7 @@ int SampleEnvironment::interceptSurfaces(Track &track) const {
/**
* @param component An object defining some component of the environment
*/
void SampleEnvironment::add(const Object_const_sptr &component) {
void SampleEnvironment::add(const IObject_const_sptr &component) {
m_components.emplace_back(component);
}
}
......
......@@ -60,7 +60,7 @@ void SampleEnvironmentSpec::addContainer(const Container_const_sptr &can) {
* Add a non-can component to the specification
* @param component A pointer to a Object
*/
void SampleEnvironmentSpec::addComponent(const Object_const_sptr &component) {
void SampleEnvironmentSpec::addComponent(const IObject_const_sptr &component) {
m_components.emplace_back(component);
}
......
......@@ -14,6 +14,8 @@
#include "Poco/SAX/InputSource.h"
#include "Poco/SAX/SAXException.h"
#include <boost/make_shared.hpp>
using namespace Poco::XML;
//------------------------------------------------------------------------------
......@@ -157,7 +159,7 @@ void SampleEnvironmentSpecParser::parseAndAddComponents(
if (nodeName == CONTAINERS_TAG) {
parseAndAddContainers(spec, childElement);
} else if (nodeName == COMPONENT_TAG) {
spec->addComponent(parseComponent<CSGObject>(childElement));
spec->addComponent(parseComponent(childElement));
}
node = nodeIter.nextNode();
}
......@@ -191,7 +193,7 @@ void SampleEnvironmentSpecParser::parseAndAddContainers(
Container_const_sptr
SampleEnvironmentSpecParser::parseContainer(Element *element) const {
using Mantid::Geometry::Container;
auto can = parseComponent<Container>(element);
auto can = boost::make_shared<Container>(parseComponent(element));
auto sampleGeometry = element->getChildElement(SAMPLEGEOMETRY_TAG);
if (sampleGeometry) {
DOMWriter writer;
......@@ -208,8 +210,7 @@ SampleEnvironmentSpecParser::parseContainer(Element *element) const {
* @param element A pointer to an XML \<container\> element
* @return A new Object instance of the given type
*/
template <typename ObjectType>
boost::shared_ptr<ObjectType>
boost::shared_ptr<IObject>
Mantid::Geometry::SampleEnvironmentSpecParser::parseComponent(
Element *element) const {
Element *geometry = element->getChildElement(COMPONENTGEOMETRY_TAG);
......@@ -219,7 +220,7 @@ Mantid::Geometry::SampleEnvironmentSpecParser::parseComponent(
COMPONENTGEOMETRY_TAG + " child tag. None found.");
}
ShapeFactory factory;
auto comp = factory.createShape<ObjectType>(geometry);
auto comp = factory.createShape(geometry);
comp->setID(element->getAttribute("id"));
auto materialID = element->getAttribute("material");
auto iter = m_materials.find(materialID);
......@@ -233,15 +234,5 @@ Mantid::Geometry::SampleEnvironmentSpecParser::parseComponent(
return comp;
}
//------------------------------------------------------------------------------
// Concrete instantions
//------------------------------------------------------------------------------
///@cond
template boost::shared_ptr<CSGObject>
Mantid::Geometry::SampleEnvironmentSpecParser::parseComponent(Element *) const;
template boost::shared_ptr<Container>
Mantid::Geometry::SampleEnvironmentSpecParser::parseComponent(Element *) const;
///@endcond
} // namespace Geometry
} // namespace Mantid
......@@ -54,8 +54,7 @@ Logger g_log("ShapeFactory");
* @return A shared pointer to a geometric shape (defaults to an 'empty' shape
*if XML tags contain no geo. info.)
*/
template <typename ObjectType>
boost::shared_ptr<ObjectType> ShapeFactory::createShape(std::string shapeXML,
boost::shared_ptr<IObject> ShapeFactory::createShape(std::string shapeXML,
bool addTypeTag) {
// wrap in a type tag
if (addTypeTag)
......@@ -70,13 +69,13 @@ boost::shared_ptr<ObjectType> ShapeFactory::createShape(std::string shapeXML,
g_log.warning("Unable to parse XML string " + shapeXML +
" . Empty geometry Object is returned.");
return boost::make_shared<ObjectType>();
return boost::make_shared<CSGObject>();
}
// Get pointer to root element
Element *pRootElem = pDoc->documentElement();
// convert into a Geometry object
return createShape<ObjectType>(pRootElem);
return createShape(pRootElem);
}
/** Creates a geometric object from a DOM-element-node pointing to an element
......@@ -87,15 +86,14 @@ boost::shared_ptr<ObjectType> ShapeFactory::createShape(std::string shapeXML,
* object. The name of this element is unimportant.
* @return A shared pointer to a geometric shape
*/
template <typename ObjectType>
boost::shared_ptr<ObjectType>
boost::shared_ptr<IObject>
ShapeFactory::createShape(Poco::XML::Element *pElem) {
// Write the definition to a string to store in the final object
std::stringstream xmlstream;
DOMWriter writer;
writer.writeNode(xmlstream, pElem);
std::string shapeXML = xmlstream.str();
auto retVal = boost::make_shared<ObjectType>(shapeXML);
auto retVal = boost::make_shared<CSGObject>(shapeXML);
// if no <algebra> element then use default algebra
bool defaultAlgebra(false);
......@@ -1479,18 +1477,5 @@ void ShapeFactory::createGeometryHandler(Poco::XML::Element *pElem,
}
}
///@cond
// Template instantations
template MANTID_GEOMETRY_DLL boost::shared_ptr<CSGObject>
ShapeFactory::createShape(std::string shapeXML, bool addTypeTag);
template MANTID_GEOMETRY_DLL boost::shared_ptr<Container>
ShapeFactory::createShape(std::string shapeXML, bool addTypeTag);
template MANTID_GEOMETRY_DLL boost::shared_ptr<CSGObject>
ShapeFactory::createShape(Poco::XML::Element *pElem);
template MANTID_GEOMETRY_DLL boost::shared_ptr<Container>
ShapeFactory::createShape(Poco::XML::Element *pElem);
///@endcond
} // namespace Geometry
} // namespace Mantid
......@@ -80,17 +80,18 @@ public:
}
void testCopyConstructorGivesObjectWithSameAttributes() {
Object_sptr original = ComponentCreationHelper::createSphere(1.0);
original->setID("sp-1");
auto original_ptr = ComponentCreationHelper::createSphere(1.0);
auto &original = dynamic_cast<CSGObject&>(*original_ptr);
original.setID("sp-1");
int objType(-1);
double radius(-1.0), height(-1.0);
std::vector<V3D> pts;
original->GetObjectGeom(objType, pts, radius, height);
original.GetObjectGeom(objType, pts, radius, height);
TS_ASSERT_EQUALS(3, objType);
TS_ASSERT(boost::dynamic_pointer_cast<GluGeometryHandler>(
original->getGeometryHandler()));
original.getGeometryHandler()));
CSGObject copy(*original);
CSGObject copy(original);
// The copy should be a primitive object with a GluGeometryHandler
objType = -1;
copy.GetObjectGeom(objType, pts, radius, height);
......@@ -99,25 +100,26 @@ public:
TS_ASSERT_EQUALS(3, objType);
TS_ASSERT(boost::dynamic_pointer_cast<GluGeometryHandler>(
copy.getGeometryHandler()));
TS_ASSERT_EQUALS(copy.getName(), original->getName());
TS_ASSERT_EQUALS(copy.getName(), original.getName());
// Check the string representation is the same
TS_ASSERT_EQUALS(copy.str(), original->str());
TS_ASSERT_EQUALS(copy.getSurfaceIndex(), original->getSurfaceIndex());
TS_ASSERT_EQUALS(copy.str(), original.str());
TS_ASSERT_EQUALS(copy.getSurfaceIndex(), original.getSurfaceIndex());
}
void testAssignmentOperatorGivesObjectWithSameAttributes() {
Object_sptr original = ComponentCreationHelper::createSphere(1.0);
original->setID("sp-1");
auto original_ptr = ComponentCreationHelper::createSphere(1.0);
auto &original = dynamic_cast<CSGObject&>(*original_ptr);
original.setID("sp-1");
int objType(-1);
double radius(-1.0), height(-1.0);
std::vector<V3D> pts;
original->GetObjectGeom(objType, pts, radius, height);
original.GetObjectGeom(objType, pts, radius, height);
TS_ASSERT_EQUALS(3, objType);
TS_ASSERT(boost::dynamic_pointer_cast<GluGeometryHandler>(
original->getGeometryHandler()));
original.getGeometryHandler()));
CSGObject lhs; // initialize
lhs = *original; // assign
lhs = original; // assign