Implementing intersection and union operators for BoundingBox.

This commit is contained in:
Patrick Shriwise 2019-07-18 13:15:26 -05:00
parent 07c9083446
commit 81bf0a67da
3 changed files with 30 additions and 19 deletions

View file

@ -50,26 +50,38 @@ struct BoundingBox
double zmin = -INFTY;
double zmax = INFTY;
// in-place update to include another bounding box
inline void update(const BoundingBox& other) {
xmin = std::min(xmin, other.xmin);
xmax = std::max(xmax, other.xmax);
ymin = std::min(ymin, other.ymin);
ymax = std::max(ymax, other.ymax);
zmin = std::min(zmin, other.zmin);
zmax = std::max(zmax, other.zmax);
};
// in-place intersection with another bounding box
inline void intersect(const BoundingBox& other) {
inline BoundingBox operator &(const BoundingBox& other) {
BoundingBox result = *this;
return result &= other;
}
inline BoundingBox operator |(const BoundingBox& other) {
BoundingBox result = *this;
return result |= other;
}
// intersect operator
inline BoundingBox& operator &=(const BoundingBox& other) {
xmin = std::max(xmin, other.xmin);
xmax = std::min(xmax, other.xmax);
ymin = std::max(ymin, other.ymin);
ymax = std::min(ymax, other.ymax);
zmin = std::max(zmin, other.zmin);
zmax = std::min(zmax, other.zmax);
return *this;
}
// union operator
inline BoundingBox& operator |=(const BoundingBox& other) {
xmin = std::min(xmin, other.xmin);
xmax = std::max(xmax, other.xmax);
ymin = std::min(ymin, other.ymin);
ymax = std::max(ymax, other.ymax);
zmin = std::min(zmin, other.zmin);
zmax = std::max(zmax, other.zmax);
return *this;
}
};

View file

@ -213,7 +213,7 @@ BoundingBox Universe::bounding_box() const {
} else {
for (const auto& cell : cells_) {
auto& c = model::cells[cell];
bbox.update(c->bounding_box());
bbox |= c->bounding_box();
}
}
return bbox;
@ -581,7 +581,7 @@ CSGCell::to_hdf5(hid_t cell_group) const
BoundingBox CSGCell::bounding_box_simple() const {
BoundingBox bbox;
for (int32_t token : rpn_) {
bbox.intersect(model::surfaces[abs(token)-1]->bounding_box(token > 0));
bbox &= model::surfaces[abs(token)-1]->bounding_box(token > 0);
}
return bbox;
}
@ -603,9 +603,9 @@ BoundingBox CSGCell::bounding_box_complex(std::vector<int32_t> rpn) const {
if (two >= OP_UNION) {
if (two == OP_UNION) {
current.update(model::surfaces[abs(one)-1]->bounding_box(one > 0));
current |= model::surfaces[abs(one)-1]->bounding_box(one > 0);
} else if (two == OP_INTERSECTION) {
current.intersect(model::surfaces[abs(one)-1]->bounding_box(one > 0));
current &= model::surfaces[abs(one)-1]->bounding_box(one > 0);
}
} else {
// two surfaces in a row, create sub-rpn for region in parenthesis
@ -638,9 +638,9 @@ BoundingBox CSGCell::bounding_box_complex(std::vector<int32_t> rpn) const {
BoundingBox sub_box = bounding_box_complex(subrpn);
// combine the sub-rpn bounding box with our current cell box
if (op == OP_UNION) {
current.update(sub_box);
current |= sub_box;
} else if (op == OP_INTERSECTION) {
current.intersect(sub_box);
current &= sub_box;
}
}
}

View file

@ -1191,8 +1191,7 @@ void read_surfaces(pugi::xml_node node)
}
// See if this surface makes part of the global bounding box.
BoundingBox bb = surf->bounding_box(true);
bb.intersect(surf->bounding_box(false));
auto bb = surf->bounding_box(true) & surf->bounding_box(false);
if (bb.xmin > -INFTY && bb.xmin < xmin) {
xmin = bb.xmin;
i_xmin = i_surf;