retain transformations on collection nodes during 2d boolean op handling

This commit is contained in:
Thomas Krijnen
2020-09-28 15:26:03 +02:00
parent e45ad15d91
commit 2905900d5c
+48 -19
View File
@@ -1175,33 +1175,49 @@ bool CgalKernel::process_as_2d_polygon(const taxonomy::boolean_result* br, std::
return false;
}
typedef std::pair<Eigen::Matrix4d*, taxonomy::extrusion*> extrusion_pair;
// @todo delete extrusion_pair.first
auto& ops = br->children;
std::vector<taxonomy::extrusion*> extrusions;
std::vector<extrusion_pair> extrusions;
std::transform(ops.begin(), ops.end(), std::back_inserter(extrusions), [](taxonomy::item* op) {
static taxonomy::extrusion* nptr = nullptr;
static std::pair<Eigen::Matrix4d*, taxonomy::extrusion*> nptr = { nullptr, nullptr };
Eigen::Matrix4d* m4 = nullptr;
if (op->kind() == taxonomy::EXTRUSION) {
return (taxonomy::extrusion*) op;
return std::make_pair(m4, (taxonomy::extrusion*) op);
}
if (op->kind() != taxonomy::COLLECTION) return nptr;
auto cl = (taxonomy::collection*) op;
if ((cl)->children.size() != 1) return nptr;
m4 = new Eigen::Matrix4d(*cl->matrix.components);
if (cl->children[0]->kind() == taxonomy::COLLECTION) {
cl = (taxonomy::collection*) cl->children[0];
if ((cl)->children.size() != 1) return nptr;
if ((cl)->children.size() != 1) {
delete m4;
return nptr;
}
(*m4) = (*m4) * *cl->matrix.components;
}
if (cl->children[0]->kind() != taxonomy::EXTRUSION) {
delete m4;
return nptr;
}
if (cl->children[0]->kind() != taxonomy::EXTRUSION) return nptr;
auto ex = (taxonomy::extrusion*) cl->children[0];
return ex;
return std::make_pair(m4, ex);
});
if (std::find(extrusions.begin(), extrusions.end(), nullptr) != extrusions.end()) {
if (std::find_if(extrusions.begin(), extrusions.end(), [](extrusion_pair& p) {
return p.second == nullptr;
}) != extrusions.end()) {
return false;
}
// op[i].matrix[2,0:3] = <0 0 1>
Eigen::Vector3d Z(0., 0., 1.);
if (std::find_if(extrusions.begin(), extrusions.end(), [&Z](taxonomy::extrusion* ex) {
if (std::find_if(extrusions.begin(), extrusions.end(), [&Z](extrusion_pair& p) {
// @todo factor in p.first;
auto ex = p.second;
auto& m = *ex->matrix.components;
return std::abs(1. - std::abs(m.col(2).head<3>().dot(Z))) > 1.e-5;
}) != extrusions.end()) {
@@ -1209,7 +1225,8 @@ bool CgalKernel::process_as_2d_polygon(const taxonomy::boolean_result* br, std::
}
// | op[i].matrix[2,0:3] . op[i].direction | = 1
if (std::find_if(extrusions.begin(), extrusions.end(), [](taxonomy::extrusion* ex) {
if (std::find_if(extrusions.begin(), extrusions.end(), [](extrusion_pair& p) {
auto ex = p.second;
auto& d = *ex->direction.components;
auto& m = *ex->matrix.components;
return std::abs(1. - std::abs(m.col(2).head<3>().dot(d))) > 1.e-5;
@@ -1218,15 +1235,17 @@ bool CgalKernel::process_as_2d_polygon(const taxonomy::boolean_result* br, std::
}
// op[0].depth <= op[i..n].depth
const auto& op_0_depth = extrusions[0]->depth;
if (std::find_if(extrusions.begin() + 1, extrusions.end(), [&op_0_depth](taxonomy::extrusion* ex) {
const auto& op_0_depth = extrusions[0].second->depth;
if (std::find_if(extrusions.begin() + 1, extrusions.end(), [&op_0_depth](extrusion_pair& p) {
auto ex = p.second;
return op_0_depth > ex->depth;
}) != extrusions.end()) {
return false;
}
const auto& op_0_matrix_2_3 = (*extrusions[0]->matrix.components)(2, 3);
if (std::find_if(extrusions.begin() + 1, extrusions.end(), [&op_0_matrix_2_3](taxonomy::extrusion* ex) {
const auto& op_0_matrix_2_3 = (*extrusions[0].second->matrix.components)(2, 3);
if (std::find_if(extrusions.begin() + 1, extrusions.end(), [&op_0_matrix_2_3](extrusion_pair& p) {
auto ex = p.second;
return op_0_matrix_2_3 < (*ex->matrix.components)(2, 3);
}) != extrusions.end()) {
return false;
@@ -1234,13 +1253,19 @@ bool CgalKernel::process_as_2d_polygon(const taxonomy::boolean_result* br, std::
std::vector<cgal_wire_t> wires;
try {
std::transform(extrusions.begin(), extrusions.end(), std::back_inserter(wires), [this](taxonomy::extrusion* ex) {
std::transform(extrusions.begin(), extrusions.end(), std::back_inserter(wires), [this](extrusion_pair& p) {
auto ex = p.second;
if (ex->basis.children.size() == 1 && ex->basis.children[0]->kind() == taxonomy::LOOP) {
auto l = (taxonomy::loop*) ex->basis.children[0];
cgal_wire_t w;
cgal_placement_t trsf;
convert_placement(ex->matrix, trsf);
cgal_placement_t trsf2;
if (p.first) {
convert_placement(*p.first, trsf2);
}
/*
std::array<std::array<double, 4>, 4> mat;
for (int i = 0; i < 4; ++i) {
@@ -1251,8 +1276,12 @@ bool CgalKernel::process_as_2d_polygon(const taxonomy::boolean_result* br, std::
*/
if (convert(l, w)) {
for (auto& p : w) {
p = p.transform(trsf);
for (auto& pt : w) {
// @todo figure out order.
pt = pt.transform(trsf);
if (p.first) {
pt = pt.transform(trsf2);
}
}
return w;
}
@@ -1266,12 +1295,12 @@ bool CgalKernel::process_as_2d_polygon(const taxonomy::boolean_result* br, std::
loops.clear();
std::transform(wires.begin(), wires.end(), std::back_inserter(loops), wire_to_polygon_2);
auto& op_0_matrix = *extrusions[0]->matrix.components;
auto& op_0_matrix = *extrusions[0].second->matrix.components;
Eigen::Vector4d op_0_dir;
op_0_dir << (*extrusions[0]->direction.components), 0;
op_0_dir << (*extrusions[0].second->direction.components), 0;
op_0_dir = op_0_matrix * op_0_dir;
z0 = op_0_matrix_2_3;
z1 = z0 + extrusions[0]->depth * op_0_dir(2);
z1 = z0 + extrusions[0].second->depth * op_0_dir(2);
if (z1 < z0) {
std::swap(z0, z1);