Commit a72dfc2b authored by Martyn Gigg's avatar Martyn Gigg
Browse files

Fix bug complement rule parsing in Object::procString

Assign the correct rule number when passing a single rule to
Object::procPair. The method detected that only one rule was present
correctly but failed to tell the external code which one it had found.
This led to the rule map being updated incorrectly.

The commit also switches the order in which the rules are assigned in
Intersection constructor to be consistent with the rest of the class
and the Union operation.
parent bdf5a7c8
......@@ -341,9 +341,11 @@ int Object::procPair(std::string &Ln,
}
if (Rend == Ln.size() ||
!Mantid::Kernel::Strings::convert(Ln.c_str() + Rend + 1, Rb) ||
Rlist.find(Rb) == Rlist.end())
Rlist.find(Rb) == Rlist.end()) {
// No second rule but we did find the first one
compUnit = Ra;
return 0;
}
// Get end of number (digital)
for (Rend++; Rend < Ln.size() && Ln[Rend] >= '0' && Ln[Rend] <= '9'; Rend++)
;
......@@ -509,6 +511,12 @@ int Object::createSurfaceList(const int outFlag) {
}
}
}
// Remove duplicates
sort(SurList.begin(), SurList.end());
auto sc = unique(SurList.begin(), SurList.end());
if (sc != SurList.end()) {
SurList.erase(sc, SurList.end());
}
if (outFlag) {
std::vector<const Surface *>::const_iterator vc;
......
......@@ -54,7 +54,7 @@ namespace Geometry {
using Kernel::V3D;
Intersection::Intersection(std::unique_ptr<Rule> Ix, std::unique_ptr<Rule> Iy)
: Rule(), A(std::move(Iy)), B(std::move(Ix))
: Rule(), A(std::move(Ix)), B(std::move(Iy))
/**
Intersection constructor from two Rule ptrs.
- Sets A,B's parents to *this
......
......@@ -17,6 +17,7 @@
#include "MantidGeometry/Surfaces/Plane.h"
#include "MantidGeometry/Math/Algebra.h"
#include "MantidGeometry/Surfaces/SurfaceFactory.h"
#include "MantidGeometry/Objects/Rules.h"
#include "MantidGeometry/Objects/Track.h"
#include "MantidGeometry/Rendering/GluGeometryHandler.h"
#include "MantidGeometry/Objects/ShapeFactory.h"
......@@ -101,7 +102,7 @@ public:
void testCreateUnitCube() {
Object_sptr geom_obj = createUnitCube();
TS_ASSERT_EQUALS(geom_obj->str(), "68 -6 5 -4 3 -2 1");
TS_ASSERT_EQUALS(geom_obj->str(), "68 1 -2 3 -4 5 -6");
double xmin(0.0), xmax(0.0), ymin(0.0), ymax(0.0), zmin(0.0), zmax(0.0);
geom_obj->getBoundingBox(xmax, ymax, zmax, xmin, ymin, zmin);
......@@ -392,7 +393,7 @@ public:
checkTrackIntercept(track, expectedResults);
}
void xtestTrackTwoIsolatedCubes()
void testTrackTwoIsolatedCubes()
/**
Test a track going through an object
*/
......@@ -549,6 +550,48 @@ public:
checkTrackIntercept(TL, expectedResults);
}
void testComplementWithTwoPrimitives() {
auto shell = createSphericalShell();
TS_ASSERT_EQUALS(2, shell->getSurfaceIndex().size());
// Are the rules correct?
const Rule *headRule = shell->topRule();
TS_ASSERT_EQUALS("Intersection", headRule->className());
const Rule *leaf1 = headRule->leaf(0);
TS_ASSERT_EQUALS("SurfPoint", leaf1->className());
auto surfPt1 = dynamic_cast<const SurfPoint *>(leaf1);
TS_ASSERT(surfPt1);
TS_ASSERT_EQUALS(1, surfPt1->getKeyN());
auto outer = dynamic_cast<const Sphere *>(surfPt1->getKey());
TS_ASSERT(outer);
TS_ASSERT_DELTA(1.0, outer->getRadius(), 1e-10);
const Rule *leaf2 = headRule->leaf(1);
TS_ASSERT_EQUALS("CompGrp", leaf2->className());
auto compRule = dynamic_cast<const CompGrp *>(leaf2);
TS_ASSERT(compRule);
TS_ASSERT_EQUALS("SurfPoint", compRule->leaf(0)->className());
auto surfPt2 = dynamic_cast<const SurfPoint *>(compRule->leaf(0));
TS_ASSERT_EQUALS(2, surfPt2->getKeyN());
auto inner = dynamic_cast<const Sphere *>(surfPt2->getKey());
TS_ASSERT(inner);
TS_ASSERT_DELTA(0.5, inner->getRadius(), 1e-10);
TS_ASSERT_EQUALS(false, shell->isValid(V3D(0, 0, 0)));
Track p1(V3D(-2, 0, 0), V3D(1, 0, 0));
int nsegments = shell->interceptSurface(p1);
TS_ASSERT_EQUALS(2, nsegments);
// total traversed distance -> 2*(r2-r1)
double distanceInside(0.0);
std::for_each(p1.cbegin(), p1.cend(),
[&distanceInside](const Link &segment) {
distanceInside += segment.distInsideObject;
});
TS_ASSERT_DELTA(1.0, distanceInside, 1e-10);
}
void testFindPointInCube()
/**
Test find point in cube
......@@ -956,6 +999,26 @@ private:
return retVal;
}
Object_sptr createSphericalShell() {
// First create some surfaces
auto outer = boost::make_shared<Sphere>();
outer->setName(1);
outer->setRadius(1.0);
auto inner = boost::make_shared<Sphere>();
inner->setName(2);
inner->setRadius(0.5);
std::map<int, boost::shared_ptr<Surface>> surfaces = {{1, outer},
{2, inner}};
// algebra string is outer with intersection of complement of inner
const std::string algebra = "(-1) # (-2)";
auto shell = boost::make_shared<Object>();
shell->setObject(21, algebra);
shell->populate(surfaces);
return shell;
}
void clearSurfMap()
/**
Clears the surface map for a new test
......
......@@ -58,9 +58,9 @@ public:
auto ptrS1 = S1.get();
auto ptrS2 = S2.get();
Intersection A(std::move(S1), std::move(S2));
TS_ASSERT_EQUALS(A.leaf(0), ptrS2);
TS_ASSERT_EQUALS(A.leaf(1), ptrS1);
TS_ASSERT_EQUALS(A.display(), "-11 10");
TS_ASSERT_EQUALS(A.leaf(0), ptrS1);
TS_ASSERT_EQUALS(A.leaf(1), ptrS2);
TS_ASSERT_EQUALS(A.display(), "10 -11");
}
void testThreeRuleConstructor() {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment