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, ...@@ -341,9 +341,11 @@ int Object::procPair(std::string &Ln,
} }
if (Rend == Ln.size() || if (Rend == Ln.size() ||
!Mantid::Kernel::Strings::convert(Ln.c_str() + Rend + 1, Rb) || !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; return 0;
}
// Get end of number (digital) // Get end of number (digital)
for (Rend++; Rend < Ln.size() && Ln[Rend] >= '0' && Ln[Rend] <= '9'; Rend++) for (Rend++; Rend < Ln.size() && Ln[Rend] >= '0' && Ln[Rend] <= '9'; Rend++)
; ;
...@@ -509,6 +511,12 @@ int Object::createSurfaceList(const int outFlag) { ...@@ -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) { if (outFlag) {
std::vector<const Surface *>::const_iterator vc; std::vector<const Surface *>::const_iterator vc;
......
...@@ -54,7 +54,7 @@ namespace Geometry { ...@@ -54,7 +54,7 @@ namespace Geometry {
using Kernel::V3D; using Kernel::V3D;
Intersection::Intersection(std::unique_ptr<Rule> Ix, std::unique_ptr<Rule> Iy) 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. Intersection constructor from two Rule ptrs.
- Sets A,B's parents to *this - Sets A,B's parents to *this
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "MantidGeometry/Surfaces/Plane.h" #include "MantidGeometry/Surfaces/Plane.h"
#include "MantidGeometry/Math/Algebra.h" #include "MantidGeometry/Math/Algebra.h"
#include "MantidGeometry/Surfaces/SurfaceFactory.h" #include "MantidGeometry/Surfaces/SurfaceFactory.h"
#include "MantidGeometry/Objects/Rules.h"
#include "MantidGeometry/Objects/Track.h" #include "MantidGeometry/Objects/Track.h"
#include "MantidGeometry/Rendering/GluGeometryHandler.h" #include "MantidGeometry/Rendering/GluGeometryHandler.h"
#include "MantidGeometry/Objects/ShapeFactory.h" #include "MantidGeometry/Objects/ShapeFactory.h"
...@@ -101,7 +102,7 @@ public: ...@@ -101,7 +102,7 @@ public:
void testCreateUnitCube() { void testCreateUnitCube() {
Object_sptr geom_obj = createUnitCube(); 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); 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); geom_obj->getBoundingBox(xmax, ymax, zmax, xmin, ymin, zmin);
...@@ -392,7 +393,7 @@ public: ...@@ -392,7 +393,7 @@ public:
checkTrackIntercept(track, expectedResults); checkTrackIntercept(track, expectedResults);
} }
void xtestTrackTwoIsolatedCubes() void testTrackTwoIsolatedCubes()
/** /**
Test a track going through an object Test a track going through an object
*/ */
...@@ -549,6 +550,48 @@ public: ...@@ -549,6 +550,48 @@ public:
checkTrackIntercept(TL, expectedResults); 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() void testFindPointInCube()
/** /**
Test find point in cube Test find point in cube
...@@ -956,6 +999,26 @@ private: ...@@ -956,6 +999,26 @@ private:
return retVal; 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() void clearSurfMap()
/** /**
Clears the surface map for a new test Clears the surface map for a new test
......
...@@ -58,9 +58,9 @@ public: ...@@ -58,9 +58,9 @@ public:
auto ptrS1 = S1.get(); auto ptrS1 = S1.get();
auto ptrS2 = S2.get(); auto ptrS2 = S2.get();
Intersection A(std::move(S1), std::move(S2)); Intersection A(std::move(S1), std::move(S2));
TS_ASSERT_EQUALS(A.leaf(0), ptrS2); TS_ASSERT_EQUALS(A.leaf(0), ptrS1);
TS_ASSERT_EQUALS(A.leaf(1), ptrS1); TS_ASSERT_EQUALS(A.leaf(1), ptrS2);
TS_ASSERT_EQUALS(A.display(), "-11 10"); TS_ASSERT_EQUALS(A.display(), "10 -11");
} }
void testThreeRuleConstructor() { 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