Major update: taxonomy shared pointers, collection type safety, work towards hashing

This commit is contained in:
Thomas Krijnen
2023-07-27 16:42:06 +08:00
parent 98a73f1646
commit 65a5646bf0
122 changed files with 1669 additions and 1203 deletions
+113 -116
View File
@@ -151,17 +151,15 @@ CGAL::Nef_polyhedron_3<Kernel_> ifcopenshell::geometry::utils::create_nef_polyhe
}
#endif
bool CgalKernel::convert(const taxonomy::shell* l, cgal_shape_t& shape) {
auto faces = l->children_as<taxonomy::face>();
if (faces.size() > 100) {
bool CgalKernel::convert(const taxonomy::shell::ptr l, cgal_shape_t& shape) {
if (l->children.size() > 100) {
static double inf = 1.e9; // std::numeric_limits<double>::infinity();
std::pair<Eigen::Vector3d, Eigen::Vector3d> minmax(
Eigen::Vector3d(+inf, +inf, +inf),
Eigen::Vector3d(-inf, -inf, -inf)
);
size_t num_points = 0;
visit_2<taxonomy::point3>(l, [&minmax, &num_points](const taxonomy::point3* p) {
visit_2<taxonomy::point3, taxonomy::shell>(l, [&minmax, &num_points](const taxonomy::point3::ptr p) {
auto& c = p->ccomponents();
++num_points;
for (int i = 0; i < 3; ++i) {
@@ -187,7 +185,7 @@ bool CgalKernel::convert(const taxonomy::shell* l, cgal_shape_t& shape) {
}
std::list<cgal_face_t> face_list;
for (auto& f : faces) {
for (auto& f : l->children) {
bool success = false;
cgal_face_t face;
@@ -212,12 +210,10 @@ bool CgalKernel::convert(const taxonomy::shell* l, cgal_shape_t& shape) {
return shape.size_of_facets();
}
bool CgalKernel::convert(const taxonomy::face* face, cgal_face_t& result) {
auto bounds = face->children_as<taxonomy::loop>();
bool CgalKernel::convert(const taxonomy::face::ptr face, cgal_face_t& result) {
int num_outer_bounds = 0;
for (auto& bound : bounds) {
for (auto& bound : face->children) {
if (bound->external.get_value_or(false)) num_outer_bounds++;
}
@@ -228,7 +224,7 @@ bool CgalKernel::convert(const taxonomy::face* face, cgal_face_t& result) {
cgal_face_t mf;
for (auto& bound : bounds) {
for (auto& bound : face->children) {
const bool is_interior = !bound->external.get_value_or(false);
@@ -257,28 +253,26 @@ bool CgalKernel::convert(const taxonomy::face* face, cgal_face_t& result) {
namespace {
// @todo obsolete?
bool convert_curve(CgalKernel* kernel, const taxonomy::item* curve, cgal_wire_t& builder) {
if (curve->kind() == taxonomy::EDGE) {
auto e = (taxonomy::edge*) curve;
bool convert_curve(CgalKernel* kernel, const taxonomy::ptr curve, cgal_wire_t& builder) {
if (auto e = taxonomy::dcast<taxonomy::edge>(curve)) {
if (true || e->basis == nullptr) {
if (builder.empty()) {
const auto& p = boost::get<taxonomy::point3>(e->start);
cgal_point_t pnt(p.ccomponents()(0), p.ccomponents()(1), p.ccomponents()(2));
const auto& p = boost::get<taxonomy::point3::ptr>(e->start);
cgal_point_t pnt(p->ccomponents()(0), p->ccomponents()(1), p->ccomponents()(2));
builder.push_back(pnt);
}
const auto& p = boost::get<taxonomy::point3>(e->end);
cgal_point_t pnt(p.ccomponents()(0), p.ccomponents()(1), p.ccomponents()(2));
const auto& p = boost::get<taxonomy::point3::ptr>(e->end);
cgal_point_t pnt(p->ccomponents()(0), p->ccomponents()(1), p->ccomponents()(2));
builder.push_back(pnt);
} else if (e->basis->kind() == taxonomy::CIRCLE) {
// @todo
} else if (e->basis->kind() == taxonomy::ELLIPSE) {
// @todo
} else {
throw std::runtime_error("Not implemented basis kind");
}
} else if (curve->kind() == taxonomy::LOOP) {
const auto& edges = ((taxonomy::loop*) curve)->children;
for (auto& c : edges) {
} else if (auto lp = taxonomy::dcast<taxonomy::loop>(curve)) {
for (auto& c : lp->children) {
convert_curve(kernel, c, builder);
}
} else {
@@ -295,34 +289,34 @@ namespace {
+std::numeric_limits<double>::infinity()
};
void evaluate_curve(const taxonomy::line& c, double u, taxonomy::point3& p) {
void evaluate_curve(const taxonomy::line::ptr& c, double u, taxonomy::point3& p) {
Eigen::Vector4d xy{ u, 0, 0, 1. };
p.components() = (c.matrix.ccomponents() * xy).head<3>();
p.components() = (c->matrix->ccomponents() * xy).head<3>();
}
void evaluate_curve(const taxonomy::circle& c, double u, taxonomy::point3& p) {
Eigen::Vector4d xy{ c.radius * std::cos(u), c.radius * std::sin(u), 0, 1. };
p.components() = (c.matrix.ccomponents() * xy).head<3>();
void evaluate_curve(const taxonomy::circle::ptr& c, double u, taxonomy::point3& p) {
Eigen::Vector4d xy{ c->radius * std::cos(u), c->radius * std::sin(u), 0, 1. };
p.components() = (c->matrix->ccomponents() * xy).head<3>();
}
void evaluate_curve(const taxonomy::ellipse& c, double u, taxonomy::point3& p) {
Eigen::Vector4d xy{ c.radius * std::cos(u), c.radius2 * std::sin(u), 0, 1. };
p.components() = (c.matrix.ccomponents() * xy).head<3>();
void evaluate_curve(const taxonomy::ellipse::ptr& c, double u, taxonomy::point3& p) {
Eigen::Vector4d xy{ c->radius * std::cos(u), c->radius2 * std::sin(u), 0, 1. };
p.components() = (c->matrix->ccomponents() * xy).head<3>();
}
// ----
void project_onto_curve(const taxonomy::line& c, const taxonomy::point3& p, double& u) {
u = (c.matrix.ccomponents().inverse() * p.ccomponents().homogeneous())(0);
void project_onto_curve(const taxonomy::line::ptr& c, const taxonomy::point3& p, double& u) {
u = (c->matrix->ccomponents().inverse() * p.ccomponents().homogeneous())(0);
}
void project_onto_curve(const taxonomy::circle& c, const taxonomy::point3& p, double& u) {
Eigen::Vector2d xy = (c.matrix.ccomponents().inverse() * p.ccomponents().homogeneous()).head<2>();
void project_onto_curve(const taxonomy::circle::ptr& c, const taxonomy::point3& p, double& u) {
Eigen::Vector2d xy = (c->matrix->ccomponents().inverse() * p.ccomponents().homogeneous()).head<2>();
u = std::atan2(xy(1), xy(0));
}
void project_onto_curve(const taxonomy::ellipse& c, const taxonomy::point3& p, double& u) {
Eigen::Vector2d xy = (c.matrix.ccomponents().inverse() * p.ccomponents().homogeneous()).head<2>();
void project_onto_curve(const taxonomy::ellipse::ptr& c, const taxonomy::point3& p, double& u) {
Eigen::Vector2d xy = (c->matrix->ccomponents().inverse() * p.ccomponents().homogeneous()).head<2>();
u = std::atan2(xy(1), xy(0));
}
@@ -331,30 +325,30 @@ namespace {
double u;
typedef void result_type;
void operator()(const taxonomy::line& c) {
void operator()(const taxonomy::line::ptr& c) {
project_onto_curve(c, p, u);
}
void operator()(const taxonomy::circle& c) {
void operator()(const taxonomy::circle::ptr& c) {
project_onto_curve(c, p, u);
}
void operator()(const taxonomy::ellipse& c) {
void operator()(const taxonomy::ellipse::ptr& c) {
project_onto_curve(c, p, u);
}
void operator()(const taxonomy::item& c) {
void operator()(const taxonomy::item::ptr&) {
throw std::runtime_error("Point projection not implemented on this geometry type");
}
};
struct point_projection_visitor {
taxonomy::item* curve;
taxonomy::ptr curve;
double u;
typedef void result_type;
void operator()(const taxonomy::point3& p) {
point_projection_visitor_ v{ p };
void operator()(const taxonomy::point3::ptr& p) {
point_projection_visitor_ v{ *p };
dispatch_curve_creation<point_projection_visitor_>::dispatch(curve, v);
u = v.u;
}
@@ -373,7 +367,7 @@ namespace {
cgal_curve_creation_visitor() : param(unbounded) {}
cgal_curve_creation_visitor(const parameter_range& p) : param(p) {}
void operator()(const taxonomy::line& l) {
void operator()(const taxonomy::line::ptr& l) {
if (param == unbounded) {
throw std::runtime_error("Cannot represent infinite line segment");
}
@@ -413,39 +407,43 @@ namespace {
points.push_back(P);
}
void operator()(const taxonomy::circle& c) {
void operator()(const taxonomy::circle::ptr& c) {
evaluate_conic(c);
}
void operator()(const taxonomy::ellipse& e) {
void operator()(const taxonomy::ellipse::ptr& e) {
evaluate_conic(e);
}
void operator()(const taxonomy::trimmed_curve& e) {
point_projection_visitor v1{ e.basis }, v2{ e.basis };
boost::apply_visitor(v1, e.start);
boost::apply_visitor(v2, e.end);
void operator()(const taxonomy::trimmed_curve::ptr& e) {
point_projection_visitor v1{ e->basis }, v2{ e->basis };
boost::apply_visitor(v1, e->start);
boost::apply_visitor(v2, e->end);
if (!e.orientation.get_value_or(true)) {
if (!e->orientation.get_value_or(true)) {
std::swap(v1.u, v2.u);
}
cgal_curve_creation_visitor v({ v1.u, v2.u });
dispatch_curve_creation<cgal_curve_creation_visitor>::dispatch(e.basis, v);
dispatch_curve_creation<cgal_curve_creation_visitor>::dispatch(e->basis, v);
this->points = v.points;
if (!e.orientation.get_value_or(true)) {
if (!e->orientation.get_value_or(true)) {
std::reverse(this->points.begin(), this->points.end());
}
}
void operator()(const taxonomy::item& e) {
void operator()(const taxonomy::edge::ptr& e) {
return (*this)(taxonomy::dcast<taxonomy::trimmed_curve>(e));
}
void operator()(const taxonomy::item::ptr&) {
throw std::runtime_error("Not supported");
}
};
void convert_curve(taxonomy::item* i, std::vector<taxonomy::point3>& points) {
void convert_curve(taxonomy::ptr i, std::vector<taxonomy::point3>& points) {
cgal_curve_creation_visitor v;
dispatch_curve_creation<cgal_curve_creation_visitor>::dispatch(i, v);
points = v.points;
@@ -540,11 +538,10 @@ namespace {
}
namespace {
CGAL::Polygon_2<Kernel_> loop_to_polygon_2(taxonomy::loop* loop) {
CGAL::Polygon_2<Kernel_> loop_to_polygon_2(taxonomy::loop::ptr loop) {
CGAL::Polygon_2<Kernel_> polygon;
auto edges = loop->children_as<taxonomy::edge>();
for (auto& e : edges) {
auto& p = boost::get<taxonomy::point3>(e->start);
for (auto& e : loop->children) {
auto& p = *boost::get<taxonomy::point3::ptr>(e->start);
CGAL::Point_2<Kernel_> pnt(p.ccomponents()(0), p.ccomponents()(1));
polygon.push_back(pnt);
}
@@ -637,13 +634,12 @@ namespace {
}
bool CgalKernel::convert(const taxonomy::loop* loop, cgal_wire_t& result) {
bool CgalKernel::convert(const taxonomy::loop::ptr loop, cgal_wire_t& result) {
// @todo only implement polygonal loops
auto edges = loop->children_as<taxonomy::edge>();
std::vector<taxonomy::point3> points;
for (auto& e : edges) {
for (auto& e : loop->children) {
std::vector<taxonomy::point3> edge;
if (e->basis) {
convert_curve(e, edge);
@@ -652,8 +648,8 @@ bool CgalKernel::convert(const taxonomy::loop* loop, cgal_wire_t& result) {
}
} else {
edge = {
boost::get<taxonomy::point3>(e->start),
boost::get<taxonomy::point3>(e->end)
*boost::get<taxonomy::point3::ptr>(e->start),
*boost::get<taxonomy::point3::ptr>(e->end)
};
}
extend_wire(points, edge);
@@ -748,7 +744,7 @@ bool CgalKernel::convert(const taxonomy::loop* loop, cgal_wire_t& result) {
}
bool CgalKernel::convert_impl(const taxonomy::shell *shell, ConversionResults& results) {
bool CgalKernel::convert_impl(const taxonomy::shell::ptr shell, ConversionResults& results) {
cgal_shape_t shape;
if (!convert(shell, shape)) {
return false;
@@ -765,13 +761,13 @@ bool CgalKernel::convert_impl(const taxonomy::shell *shell, ConversionResults& r
return true;
}
bool CgalKernel::convert_impl(const taxonomy::solid *solid, ConversionResults& results) {
bool CgalKernel::convert_impl(const taxonomy::solid::ptr solid, ConversionResults& results) {
cgal_shape_t shape;
if (solid->children.empty()) {
return false;
}
// @todo
if (!convert((taxonomy::shell*)solid->children[0], shape)) {
if (!convert((taxonomy::shell::ptr)solid->children[0], shape)) {
return false;
}
if (shape.size_of_facets() == 0) {
@@ -787,9 +783,7 @@ bool CgalKernel::convert_impl(const taxonomy::solid *solid, ConversionResults& r
}
namespace {
bool convert_placement(const ifcopenshell::geometry::taxonomy::matrix4& place, cgal_placement_t& trsf) {
const auto& m = place.ccomponents();
bool convert_placement(const Eigen::Matrix4d& m, cgal_placement_t& trsf) {
// @todo check
trsf = cgal_placement_t(
m(0, 0), m(0, 1), m(0, 2), m(0, 3),
@@ -798,9 +792,12 @@ namespace {
return true;
}
bool convert_placement(ifcopenshell::geometry::taxonomy::matrix4::ptr place, cgal_placement_t& trsf) {
return convert_placement(place->ccomponents(), trsf);
}
}
bool ifcopenshell::geometry::kernels::CgalKernel::convert_openings(const IfcUtil::IfcBaseEntity * entity, const std::vector<std::pair<taxonomy::item*, ifcopenshell::geometry::taxonomy::matrix4>>& openings, const IfcGeom::ConversionResults & entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4 & entity_trsf, IfcGeom::ConversionResults & cut_shapes)
bool ifcopenshell::geometry::kernels::CgalKernel::convert_openings(const IfcUtil::IfcBaseEntity * entity, const std::vector<std::pair<taxonomy::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings, const IfcGeom::ConversionResults & entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4 & entity_trsf, IfcGeom::ConversionResults & cut_shapes)
{
#ifdef IFOPSH_SIMPLE_KERNEL
return false;
@@ -823,7 +820,7 @@ bool ifcopenshell::geometry::kernels::CgalKernel::convert_openings(const IfcUtil
cgal_shape_t entity_shape(entity_shape_unlocated);
auto gtrsf = opening_shapes[i].Placement();
// @todo check
Eigen::Matrix4d m = opening_trsf.ccomponents() * gtrsf.ccomponents();
Eigen::Matrix4d m = opening_trsf.ccomponents() * gtrsf->ccomponents();
if (!m.isIdentity()) {
cgal_placement_t trsf;
convert_placement(m, trsf);
@@ -848,7 +845,7 @@ bool ifcopenshell::geometry::kernels::CgalKernel::convert_openings(const IfcUtil
for (auto& shp : entity_shapes) {
auto entity_shape = ((CgalShape*)shp.Shape())->shape();
const auto& m = shp.Placement().ccomponents();
const auto& m = shp.Placement()->ccomponents();
if (!m.isIdentity()) {
cgal_placement_t trsf;
convert_placement(m, trsf);
@@ -872,7 +869,7 @@ bool ifcopenshell::geometry::kernels::CgalKernel::convert_openings(const IfcUtil
return false;
}
cut_shapes.push_back(IfcGeom::ConversionResult(shp.ItemId(), new CgalShape(a_poly), &shp.Style()));
cut_shapes.push_back(IfcGeom::ConversionResult(shp.ItemId(), new CgalShape(a_poly), shp.StylePtr()));
}
return true;
@@ -880,7 +877,7 @@ bool ifcopenshell::geometry::kernels::CgalKernel::convert_openings(const IfcUtil
}
bool CgalKernel::convert_impl(const taxonomy::extrusion* extrusion, ConversionResults& results) {
bool CgalKernel::convert_impl(const taxonomy::extrusion::ptr extrusion, ConversionResults& results) {
cgal_shape_t shape;
if (!convert(extrusion, shape)) {
return false;
@@ -894,14 +891,14 @@ bool CgalKernel::convert_impl(const taxonomy::extrusion* extrusion, ConversionRe
return true;
}
bool CgalKernel::process_extrusion(const cgal_face_t& bottom_face, const taxonomy::direction3& direction, double height, cgal_shape_t& shape) {
bool CgalKernel::process_extrusion(const cgal_face_t& bottom_face, taxonomy::direction3::ptr direction, double height, cgal_shape_t& shape) {
bool has_inner_bounds = !bottom_face.inner.empty();
std::list<cgal_wire_t> faces_to_extrude;
std::set<std::pair<size_t, size_t>> internal_edges;
CGAL::Cartesian_converter<CGAL::Epeck, CGAL::Simple_cartesian<double>> C;
// CGAL::Cartesian_converter<CGAL::Epeck, CGAL::Simple_cartesian<double>> C;
if (has_inner_bounds) {
CGAL::Polygon_with_holes_2<Kernel_> pwh;
@@ -966,7 +963,7 @@ bool CgalKernel::process_extrusion(const cgal_face_t& bottom_face, const taxonom
face_list.push_back(cgal_face_t{ w });
auto& fs = direction.ccomponents();
auto& fs = direction->ccomponents();
cgal_direction_t dir(fs(0), fs(1), fs(2));
int si = 0;
@@ -1065,7 +1062,7 @@ bool CgalKernel::process_extrusion(const cgal_face_t& bottom_face, const taxonom
*/
}
bool CgalKernel::convert(const taxonomy::extrusion* extrusion, cgal_shape_t &shape) {
bool CgalKernel::convert(const taxonomy::extrusion::ptr extrusion, cgal_shape_t &shape) {
const double& height = extrusion->depth;
if (height < conv_settings_.getValue(ConversionSettings::GV_PRECISION)) {
Logger::Message(Logger::LOG_ERROR, "Non-positive extrusion height encountered for:", extrusion->instance);
@@ -1073,7 +1070,7 @@ bool CgalKernel::convert(const taxonomy::extrusion* extrusion, cgal_shape_t &sha
}
cgal_face_t bottom_face;
if (!convert(&extrusion->basis, bottom_face)) {
if (!convert(extrusion->basis, bottom_face)) {
return false;
}
@@ -1270,41 +1267,41 @@ bool CgalKernel::preprocess_boolean_operand(const IfcUtil::IfcBaseClass* log_ref
#endif
bool CgalKernel::process_as_2d_polygon(const taxonomy::boolean_result* br, std::list<CGAL::Polygon_2<Kernel_>>& loops, double& z0, double& z1) {
bool CgalKernel::process_as_2d_polygon(const taxonomy::boolean_result::ptr br, std::list<CGAL::Polygon_2<Kernel_>>& loops, double& z0, double& z1) {
// @todo can also be for other boolean operations, just depth/matrix operands are different
if (br->operation != taxonomy::boolean_result::SUBTRACTION) {
return false;
}
typedef std::pair<Eigen::Matrix4d*, taxonomy::extrusion*> extrusion_pair;
typedef std::pair<Eigen::Matrix4d*, taxonomy::extrusion::ptr> extrusion_pair;
// @todo delete extrusion_pair.first
auto& ops = br->children;
std::vector<extrusion_pair> extrusions;
std::transform(ops.begin(), ops.end(), std::back_inserter(extrusions), [](taxonomy::item* op) {
static std::pair<Eigen::Matrix4d*, taxonomy::extrusion*> nptr = { nullptr, nullptr };
std::transform(ops.begin(), ops.end(), std::back_inserter(extrusions), [](taxonomy::ptr op) {
static std::pair<Eigen::Matrix4d*, taxonomy::extrusion::ptr> nptr = { nullptr, nullptr };
Eigen::Matrix4d* m4 = nullptr;
if (op->kind() == taxonomy::EXTRUSION) {
return std::make_pair(m4, (taxonomy::extrusion*) op);
if (auto ex = taxonomy::dcast<taxonomy::extrusion>(op)) {
return std::make_pair(m4, ex);
}
if (op->kind() != taxonomy::COLLECTION) return nptr;
auto cl = (taxonomy::collection*) op;
auto cl = taxonomy::dcast<taxonomy::collection>(op);
if (!cl) return nptr;
if ((cl)->children.size() != 1) return nptr;
m4 = new Eigen::Matrix4d(cl->matrix.ccomponents());
m4 = new Eigen::Matrix4d(cl->matrix->ccomponents());
if (cl->children[0]->kind() == taxonomy::COLLECTION) {
cl = (taxonomy::collection*) cl->children[0];
cl = taxonomy::cast<taxonomy::collection>(cl->children[0]);
if ((cl)->children.size() != 1) {
delete m4;
return nptr;
}
(*m4) = (*m4) * cl->matrix.ccomponents();
(*m4) = (*m4) * cl->matrix->ccomponents();
}
if (cl->children[0]->kind() != taxonomy::EXTRUSION) {
delete m4;
return nptr;
}
auto ex = (taxonomy::extrusion*) cl->children[0];
auto ex = taxonomy::cast<taxonomy::extrusion>(cl->children[0]);
return std::make_pair(m4, ex);
});
@@ -1319,7 +1316,7 @@ bool CgalKernel::process_as_2d_polygon(const taxonomy::boolean_result* br, std::
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.ccomponents();
auto& m = ex->matrix->ccomponents();
return std::abs(1. - std::abs(m.col(2).head<3>().dot(Z))) > 1.e-5;
}) != extrusions.end()) {
return false;
@@ -1328,8 +1325,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(), [](extrusion_pair& p) {
auto ex = p.second;
auto& d = ex->direction.ccomponents();
auto& m = ex->matrix.ccomponents();
auto& d = ex->direction->ccomponents();
auto& m = ex->matrix->ccomponents();
return std::abs(1. - std::abs(m.col(2).head<3>().dot(d))) > 1.e-5;
}) != extrusions.end()) {
return false;
@@ -1344,10 +1341,10 @@ bool CgalKernel::process_as_2d_polygon(const taxonomy::boolean_result* br, std::
return false;
}
const auto& op_0_matrix_2_3 = extrusions[0].second->matrix.ccomponents()(2, 3);
const auto& op_0_matrix_2_3 = extrusions[0].second->matrix->ccomponents()(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);
return op_0_matrix_2_3 < ex->matrix->components()(2, 3);
}) != extrusions.end()) {
return false;
}
@@ -1356,8 +1353,8 @@ bool CgalKernel::process_as_2d_polygon(const taxonomy::boolean_result* br, std::
try {
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];
if (ex->basis->children.size() == 1 && ex->basis->children[0]->kind() == taxonomy::LOOP) {
auto l = (taxonomy::loop::ptr) ex->basis->children[0];
cgal_wire_t w;
cgal_placement_t trsf;
convert_placement(ex->matrix, trsf);
@@ -1396,9 +1393,9 @@ 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].second->matrix.ccomponents();
auto& op_0_matrix = extrusions[0].second->matrix->ccomponents();
Eigen::Vector4d op_0_dir;
op_0_dir << extrusions[0].second->direction.ccomponents(), 0;
op_0_dir << extrusions[0].second->direction->ccomponents(), 0;
op_0_dir = op_0_matrix * op_0_dir;
z0 = op_0_matrix_2_3;
z1 = z0 + extrusions[0].second->depth * op_0_dir(2);
@@ -1501,7 +1498,7 @@ bool CgalKernel::process_as_2d_polygon(const std::list<std::list<std::pair<const
for (auto jt = it->begin(); jt != it->end(); ++jt) {
auto& nth_op = jt->second;
std::pair<Kernel_::FT, Kernel_::FT> operand_n_distance_along_normal;
if (!orthogonal_edge_length(first_op, fnorm, operand_n_distance_along_normal)) {
if (!orthogonal_edge_length(nth_op, fnorm, operand_n_distance_along_normal)) {
return false;
}
@@ -1525,7 +1522,7 @@ bool CgalKernel::process_as_2d_polygon(const std::list<std::list<std::pair<const
namespace {
template <typename It, typename Fn>
void project_onto_plane(const taxonomy::plane& p, It i, It j, Fn fn) {
auto mi = p.matrix.ccomponents().inverse();
auto mi = p.matrix->ccomponents().inverse();
Eigen::Vector4d v;
std::for_each(i, j, [&mi, &v, &fn](const cgal_shape_t& shp) {
for (auto& vv : vertices(shp)) {
@@ -1541,22 +1538,22 @@ namespace {
}
}
bool CgalKernel::convert_impl(const taxonomy::boolean_result* br, ConversionResults& results) {
bool CgalKernel::convert_impl(const taxonomy::boolean_result::ptr br, ConversionResults& results) {
double z0, z1;
std::list<CGAL::Polygon_2<Kernel_>> loops;
if (process_as_2d_polygon(br, loops, z0, z1)) {
taxonomy::style* first_item_style = nullptr;
taxonomy::style::ptr first_item_style = nullptr;
{
auto gi = dynamic_cast<const taxonomy::geom_item*>(br->children[0]);
auto gi = br->children[0];
while (gi) {
if (gi->surface_style) {
first_item_style = gi->surface_style;
break;
}
auto ci = dynamic_cast<const taxonomy::collection*>(gi);
auto ci = taxonomy::dcast<taxonomy::collection>(gi);
if (ci && ci->children.size() == 1) {
gi = dynamic_cast<const taxonomy::geom_item*>(ci->children[0]);
gi = ci->children[0];
} else {
break;
}
@@ -1614,7 +1611,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result* br, ConversionResu
);
cgal_shape_t shp;
taxonomy::direction3 d(0, 0, 1);
auto d = taxonomy::make<taxonomy::direction3>(0, 0, 1);
process_extrusion(f, d, z1 - z0, shp);
for (auto it = shp.vertices_begin(); it != shp.vertices_end(); ++it) {
@@ -1646,7 +1643,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result* br, ConversionResu
CGAL::Nef_nary_union_3<CGAL::Nef_polyhedron_3<Kernel_>> second_operand_collector;
size_t second_operand_collector_size = 0;
taxonomy::style* first_item_style = nullptr;
taxonomy::style::ptr first_item_style = nullptr;
std::list<std::pair<const IfcUtil::IfcBaseClass*, std::list<cgal_shape_t>>> operands;
@@ -1660,7 +1657,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result* br, ConversionResu
operands.back().first = c->instance->as<IfcUtil::IfcBaseClass>();
if (c->kind() == taxonomy::SOLID && c->instance->declaration().is("IfcHalfSpaceSolid") && !first) {
auto face = (taxonomy::face*) ((taxonomy::solid*) c)->children[0];
auto face = taxonomy::cast<taxonomy::solid>(c)->children[0]->children[0];
if (face->basis == nullptr || face->basis->kind() != taxonomy::PLANE) {
return false;
@@ -1671,7 +1668,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result* br, ConversionResu
double uvw_min[3] = { +inf, +inf, +inf };
double uvw_max[3] = { -inf, -inf, -inf };
auto& p = *((taxonomy::plane*)face->basis);
auto& p = *taxonomy::cast<taxonomy::plane>(face->basis);
project_onto_plane(p,
operands.front().second.begin(),
operands.front().second.end(),
@@ -1710,7 +1707,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result* br, ConversionResu
return false;
}
// static
taxonomy::direction3 z(0, 0, 1);
auto z = taxonomy::make<taxonomy::direction3>(0, 0, 1);
cgal_shape_t poly;
process_extrusion(f, z, 200, poly);
for (auto& v : vertices(poly)) {
@@ -1741,17 +1738,17 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result* br, ConversionResu
AbstractKernel::convert(c, cr);
if (first && br->operation == taxonomy::boolean_result::SUBTRACTION) {
first_item_style = ((taxonomy::geom_item*)c)->surface_style;
first_item_style = c->surface_style;
if (!first_item_style && c->kind() == taxonomy::COLLECTION) {
// @todo recursively right?
first_item_style = ((taxonomy::geom_item*) ((taxonomy::collection*)c)->children[0])->surface_style;
first_item_style = taxonomy::cast<taxonomy::collection>(c)->children[0]->surface_style;
}
}
for (auto it = cr.begin(); it != cr.end(); ++it) {
const cgal_shape_t& entity_shape_unlocated(((CgalShape*)it->Shape())->shape());
cgal_shape_t entity_shape(entity_shape_unlocated);
if (!it->Placement().is_identity()) {
if (!it->Placement()->is_identity()) {
cgal_placement_t trsf;
convert_placement(it->Placement(), trsf);
for (auto &vertex : vertices(entity_shape)) {
+12 -12
View File
@@ -91,22 +91,22 @@ namespace ifcopenshell {
void remove_duplicate_points_from_loop(cgal_wire_t& polygon);
bool convert(const taxonomy::extrusion*, cgal_shape_t&);
bool convert(const taxonomy::face*, cgal_face_t&);
bool convert(const taxonomy::loop*, cgal_wire_t&);
// bool convert(const taxonomy::matrix4*, cgal_placement_t&);
bool convert(const taxonomy::shell*, cgal_shape_t&);
bool convert(const taxonomy::extrusion::ptr, cgal_shape_t&);
bool convert(const taxonomy::face::ptr, cgal_face_t&);
bool convert(const taxonomy::loop::ptr, cgal_wire_t&);
// bool convert(const taxonomy::matrix4::ptr, cgal_placement_t&);
bool convert(const taxonomy::shell::ptr, cgal_shape_t&);
bool process_extrusion(const cgal_face_t& bottom_face, const taxonomy::direction3& direction, double height, cgal_shape_t& shape);
bool process_as_2d_polygon(const taxonomy::boolean_result* br, std::list<CGAL::Polygon_2<Kernel_>>& loops, double& z0, double& z1);
bool process_extrusion(const cgal_face_t& bottom_face, taxonomy::direction3::ptr direction, double height, cgal_shape_t& shape);
bool process_as_2d_polygon(const taxonomy::boolean_result::ptr br, std::list<CGAL::Polygon_2<Kernel_>>& loops, double& z0, double& z1);
bool process_as_2d_polygon(const std::list<std::list<std::pair<const IfcUtil::IfcBaseClass*, cgal_shape_t>>>& operands, std::list<CGAL::Polygon_2<Kernel_>>& loops, double& z0, double& z1);
virtual bool convert_impl(const taxonomy::shell*, IfcGeom::ConversionResults&);
virtual bool convert_impl(const taxonomy::extrusion*, IfcGeom::ConversionResults&);
virtual bool convert_impl(const taxonomy::boolean_result*, IfcGeom::ConversionResults&);
virtual bool convert_impl(const taxonomy::solid*, IfcGeom::ConversionResults&);
virtual bool convert_impl(const taxonomy::shell::ptr, IfcGeom::ConversionResults&);
virtual bool convert_impl(const taxonomy::extrusion::ptr, IfcGeom::ConversionResults&);
virtual bool convert_impl(const taxonomy::boolean_result::ptr, IfcGeom::ConversionResults&);
virtual bool convert_impl(const taxonomy::solid::ptr, IfcGeom::ConversionResults&);
virtual bool convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector<std::pair<taxonomy::item*, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
virtual bool convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector<std::pair<taxonomy::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes);
#ifndef IFOPSH_SIMPLE_KERNEL
@@ -406,7 +406,7 @@ namespace IfcGeom {
auto compound_generic = elem->geometry().as_compound();
auto compound = ((ifcopenshell::geometry::OpenCascadeShape*)compound_generic)->shape();
const auto& m = elem->transformation().data().ccomponents();
const auto& m = elem->transformation().data()->ccomponents();
gp_Trsf tr;
tr.SetValues(
m(0, 0), m(0, 1), m(0, 2), m(0, 3),
@@ -23,7 +23,7 @@ namespace {
void ifcopenshell::geometry::OpenCascadeShape::Triangulate(const IfcGeom::IteratorSettings& settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int surface_style_id) const {
// @todo remove duplication with OpenCascadeKernel::convert(const taxonomy::matrix4* matrix, gp_GTrsf& trsf);
// @todo remove duplication with OpenCascadeKernel::convert(const taxonomy::matrix4::ptr matrix, gp_GTrsf& trsf);
// above can be static?
// A 3x3 matrix to rotate the vertex normals
@@ -201,7 +201,7 @@ namespace {
};
}
bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector<std::pair<taxonomy::item*, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector<std::pair<taxonomy::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes) {
util::boolean_settings bst;
@@ -252,7 +252,7 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity*
auto gtrsf = opening_shapes[i].Placement();
// @todo check
Eigen::Matrix4d m = relative * gtrsf.ccomponents();
Eigen::Matrix4d m = relative * gtrsf->ccomponents();
gp_Trsf trsf;
trsf.SetValues(
m(0, 0), m(0, 1), m(0, 2), m(0, 3),
@@ -308,7 +308,7 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity*
} else {
entity_shape_unlocated = util::ensure_fit_for_subtraction(entity_part, entity_shape_solid, conv_settings_.getValue(ConversionSettings::GV_PRECISION));
}
const auto& m = it3->Placement().ccomponents();
const auto& m = it3->Placement()->ccomponents();
// @todo
// if (entity_shape_gtrsf.Form() == gp_Other) {
// Logger::Message(Logger::LOG_WARNING, "Applying non uniform transformation to:", entity);
@@ -383,7 +383,7 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity*
combined_result = C;
}
cut_shapes.push_back(IfcGeom::ConversionResult(it3->ItemId(), new OpenCascadeShape(combined_result), &it3->Style()));
cut_shapes.push_back(IfcGeom::ConversionResult(it3->ItemId(), new OpenCascadeShape(combined_result), it3->StylePtr()));
}
return true;
}
@@ -713,10 +713,10 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity*
// try {
// IfcSchema::IfcRepresentationItem::list::ptr items = representation->Items();
// if (items->size() == 1) {
// IfcSchema::IfcRepresentationItem* item = *items->begin();
// IfcSchema::IfcRepresentationptr item = *items->begin();
// if (item->declaration().is(IfcSchema::IfcMappedItem::Class())) {
// if (item->StyledByItem()->size() == 0) {
// IfcSchema::IfcMappedItem* mapped_item = item->as<IfcSchema::IfcMappedItem>();
// IfcSchema::IfcMappedptr mapped_item = item->as<IfcSchema::IfcMappedItem>();
// if (is_identity_transform(mapped_item->MappingTarget())) {
// IfcSchema::IfcRepresentationMap* map = mapped_item->MappingSource();
// if (is_identity_transform(map->MappingOrigin())) {
@@ -767,7 +767,7 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity*
// if (is_identity_transform(map->MappingOrigin())) {
// IfcSchema::IfcMappedItem::list::ptr items = map->MapUsage();
// for (IfcSchema::IfcMappedItem::list::it it = items->begin(); it != items->end(); ++it) {
// IfcSchema::IfcMappedItem* item = *it;
// IfcSchema::IfcMappedptr item = *it;
// if (item->StyledByItem()->size() != 0) continue;
//
// if (!is_identity_transform(item->MappingTarget())) {
@@ -1265,7 +1265,7 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity*
// return 0;
// }
//
// const IfcSchema::IfcRepresentationItem* IfcGeom::Kernel::find_item_carrying_style(const IfcSchema::IfcRepresentationItem* item) {
// const IfcSchema::IfcRepresentationptr IfcGeom::Kernel::find_item_carrying_style(const IfcSchema::IfcRepresentationptr item) {
// if (item->StyledByItem()->size()) {
// return item;
// }
@@ -1435,7 +1435,7 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity*
// return style_cache[surface_style_id] = surface_style_ptr_const;
// }
//
// std::shared_ptr<const IfcGeom::SurfaceStyle> IfcGeom::Kernel::get_style(const IfcSchema::IfcRepresentationItem* item) {
// std::shared_ptr<const IfcGeom::SurfaceStyle> IfcGeom::Kernel::get_style(const IfcSchema::IfcRepresentationptr item) {
// return internalize_surface_style(get_surface_style<IfcSchema::IfcSurfaceStyleShading>(item));
// }
//
@@ -81,7 +81,7 @@ private:
double eps_;
bool non_manifold_;
void loop_(const taxonomy::loop* ps, const std::function<void(int, int, bool)>& callback);
void loop_(const taxonomy::loop::ptr ps, const std::function<void(int, int, bool)>& callback);
/*
bool construct(const IfcSchema::IfcCartesianPoint* cp, gp_Pnt* l);
@@ -99,7 +99,7 @@ private:
std::vector<const void*> get_idxs(const std::vector<int>& it);
*/
public:
faceset_helper(OpenCascadeKernel* kernel, const taxonomy::shell* l);
faceset_helper(OpenCascadeKernel* kernel, const taxonomy::shell::ptr l);
~faceset_helper();
bool non_manifold() const { return non_manifold_; }
@@ -108,8 +108,8 @@ private:
bool edge(int A, int B, TopoDS_Edge& e);
bool wire(const taxonomy::loop* loop, TopoDS_Wire& wire);
bool wires(const taxonomy::loop* loop, TopTools_ListOfShape& wires);
bool wire(const taxonomy::loop::ptr loop, TopoDS_Wire& wire);
bool wires(const taxonomy::loop::ptr loop, TopTools_ListOfShape& wires);
};
faceset_helper* faceset_helper_;
@@ -130,25 +130,25 @@ public:
, precision_(settings.getValue(ConversionSettings::GV_PRECISION))
{}
bool convert(const taxonomy::extrusion*, TopoDS_Shape&);
bool convert(const taxonomy::face*, TopoDS_Shape&);
bool convert(const taxonomy::loop*, TopoDS_Wire&);
bool convert(const taxonomy::matrix4*, gp_GTrsf&);
bool convert(const taxonomy::shell*, TopoDS_Shape&);
bool convert(const taxonomy::solid*, TopoDS_Shape&);
bool convert(const taxonomy::bspline_surface* bs, Handle(Geom_Surface) surf);
bool convert(const taxonomy::extrusion::ptr, TopoDS_Shape&);
bool convert(const taxonomy::face::ptr, TopoDS_Shape&);
bool convert(const taxonomy::loop::ptr, TopoDS_Wire&);
bool convert(const taxonomy::matrix4::ptr, gp_GTrsf&);
bool convert(const taxonomy::shell::ptr, TopoDS_Shape&);
bool convert(const taxonomy::solid::ptr, TopoDS_Shape&);
bool convert(const taxonomy::bspline_surface::ptr bs, Handle(Geom_Surface) surf);
TopoDS_Shape apply_transformation(const TopoDS_Shape& s, const taxonomy::matrix4& t);
TopoDS_Shape apply_transformation(const TopoDS_Shape& s, const gp_GTrsf& t);
TopoDS_Shape apply_transformation(const TopoDS_Shape& s, const gp_Trsf& t);
virtual bool convert_impl(const taxonomy::face*, IfcGeom::ConversionResults&);
virtual bool convert_impl(const taxonomy::solid*, IfcGeom::ConversionResults&);
virtual bool convert_impl(const taxonomy::shell*, IfcGeom::ConversionResults&);
virtual bool convert_impl(const taxonomy::extrusion*, IfcGeom::ConversionResults&);
virtual bool convert_impl(const taxonomy::boolean_result*, IfcGeom::ConversionResults&);
virtual bool convert_impl(const taxonomy::face::ptr, IfcGeom::ConversionResults&);
virtual bool convert_impl(const taxonomy::solid::ptr, IfcGeom::ConversionResults&);
virtual bool convert_impl(const taxonomy::shell::ptr, IfcGeom::ConversionResults&);
virtual bool convert_impl(const taxonomy::extrusion::ptr, IfcGeom::ConversionResults&);
virtual bool convert_impl(const taxonomy::boolean_result::ptr, IfcGeom::ConversionResults&);
virtual bool convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector<std::pair<taxonomy::item*, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
virtual bool convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector<std::pair<taxonomy::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes);
template <typename T, typename U>
@@ -761,7 +761,7 @@ bool IfcGeom::util::flatten_shape_list(const IfcGeom::ConversionResults& shapes,
}
// @todo refactor, also should be GTrsf
const auto& m = it->Placement().ccomponents();
const auto& m = it->Placement()->ccomponents();
gp_Trsf trsf;
trsf.SetValues(
m(0, 0), m(0, 1), m(0, 2), m(0, 3),
@@ -43,7 +43,7 @@ namespace {
}
}
bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result* br, ConversionResults& results) {
bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result::ptr br, ConversionResults& results) {
bool valid_result = false;
bool first = true;
const double tol = conv_settings_.getValue(ConversionSettings::GV_PRECISION);
@@ -51,7 +51,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result* br, Convers
TopoDS_Shape a;
TopTools_ListOfShape b;
taxonomy::style* first_item_style = nullptr;
taxonomy::style::ptr first_item_style;
for (auto& c : br->children) {
IfcGeom::ConversionResults cr;
@@ -59,10 +59,10 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result* br, Convers
if (first && br->operation == taxonomy::boolean_result::SUBTRACTION) {
// @todo A will be null on union/intersection, intended?
IfcGeom::util::flatten_shape_list(cr, a, false, conv_settings_.getValue(ifcopenshell::geometry::ConversionSettings::GV_PRECISION));
first_item_style = ((taxonomy::geom_item*)c)->surface_style;
first_item_style = c->surface_style;
if (!first_item_style && c->kind() == taxonomy::COLLECTION) {
// @todo recursively right?
first_item_style = ((taxonomy::geom_item*) ((taxonomy::collection*)c)->children[0])->surface_style;
first_item_style = taxonomy::cast<taxonomy::geom_item>(taxonomy::cast<taxonomy::collection>(c)->children[0])->surface_style;
}
if (conv_settings_.getValue(ConversionSettings::GV_DISABLE_BOOLEAN_RESULT) > 0.0) {
@@ -84,7 +84,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result* br, Convers
for (auto& r : cr) {
auto S = ((OpenCascadeShape*)r.Shape())->shape();
gp_GTrsf trsf;
convert(&r.Placement(), trsf);
convert(r.Placement(), trsf);
// @todo it really confuses me why I cannot use Moved() here instead
S.Location(S.Location() * trsf.Trsf());
@@ -6,7 +6,7 @@ using namespace ifcopenshell::geometry;
using namespace ifcopenshell::geometry::kernels;
using namespace IfcGeom;
bool OpenCascadeKernel::convert(const taxonomy::bspline_surface* bs, Handle(Geom_Surface) surf) {
bool OpenCascadeKernel::convert(const taxonomy::bspline_surface::ptr bs, Handle(Geom_Surface) surf) {
const bool is_rational = !!bs->weights;
TColgp_Array2OfPnt Poles(0, (int)bs->control_points.size() - 1, 0, (int)(*bs->control_points.begin()).size() - 1);
@@ -22,7 +22,7 @@ bool OpenCascadeKernel::convert(const taxonomy::bspline_surface* bs, Handle(Geom
for (auto it = bs->control_points.begin(); it != bs->control_points.end(); ++it, ++i) {
j = 0;
for (auto jt = (*it).begin(); jt != (*it).end(); ++jt, ++j) {
Poles(i, j) = convert_xyz<gp_Pnt>(*jt);
Poles(i, j) = convert_xyz<gp_Pnt>(**jt);
}
}
@@ -6,7 +6,7 @@ using namespace ifcopenshell::geometry;
using namespace ifcopenshell::geometry::kernels;
using namespace IfcGeom;
bool OpenCascadeKernel::convert(const taxonomy::extrusion* extrusion, TopoDS_Shape& shape) {
bool OpenCascadeKernel::convert(const taxonomy::extrusion::ptr extrusion, TopoDS_Shape& shape) {
const double& height = extrusion->depth;
if (height < conv_settings_.getValue(ConversionSettings::GV_PRECISION)) {
@@ -15,7 +15,7 @@ bool OpenCascadeKernel::convert(const taxonomy::extrusion* extrusion, TopoDS_Sha
}
TopoDS_Shape face;
if (!convert(&extrusion->basis, face)) {
if (!convert(extrusion->basis, face)) {
return false;
}
@@ -29,7 +29,7 @@ bool OpenCascadeKernel::convert(const taxonomy::extrusion* extrusion, TopoDS_Sha
auto trsf = gtrsf.Trsf();
*/
const auto& fs = extrusion->direction.ccomponents();
const auto& fs = extrusion->direction->ccomponents();
gp_Dir dir(fs(0), fs(1), fs(2));
shape.Nullify();
@@ -71,7 +71,7 @@ bool OpenCascadeKernel::convert(const taxonomy::extrusion* extrusion, TopoDS_Sha
return !shape.IsNull();
}
bool OpenCascadeKernel::convert_impl(const taxonomy::extrusion* extrusion, IfcGeom::ConversionResults& results) {
bool OpenCascadeKernel::convert_impl(const taxonomy::extrusion::ptr extrusion, IfcGeom::ConversionResults& results) {
TopoDS_Shape shape;
if (!convert(extrusion, shape)) {
return false;
+6 -8
View File
@@ -47,9 +47,7 @@ using namespace ifcopenshell::geometry::kernels;
using namespace IfcGeom;
using namespace IfcGeom::util;
bool OpenCascadeKernel::convert(const taxonomy::face* face, TopoDS_Shape& result) {
auto bounds = face->children_as<taxonomy::loop>();
bool OpenCascadeKernel::convert(const taxonomy::face::ptr face, TopoDS_Shape& result) {
face_definition fd;
const bool is_face_surface = false; /* todo */
@@ -71,10 +69,10 @@ bool OpenCascadeKernel::convert(const taxonomy::face* face, TopoDS_Shape& result
}
*/
const int num_bounds = bounds.size();
const int num_bounds = face->children.size();
int num_outer_bounds = 0;
for (auto& bound : bounds) {
for (auto& bound : face->children) {
if (bound->external.get_value_or(false)) {
num_outer_bounds++;
}
@@ -97,7 +95,7 @@ bool OpenCascadeKernel::convert(const taxonomy::face* face, TopoDS_Shape& result
TopTools_DataMapOfShapeInteger wire_senses;
for (int process_interior = 0; process_interior <= 1; ++process_interior) {
for (auto& bound : bounds) {
for (auto& bound : face->children) {
bool same_sense = true; /* todo bound->Orientation(); */
const bool is_interior =
@@ -302,7 +300,7 @@ bool OpenCascadeKernel::convert(const taxonomy::face* face, TopoDS_Shape& result
return true;
}
bool OpenCascadeKernel::convert_impl(const taxonomy::face* face, IfcGeom::ConversionResults& results) {
bool OpenCascadeKernel::convert_impl(const taxonomy::face::ptr face, IfcGeom::ConversionResults& results) {
throw std::runtime_error("Root-level face not expected");
/*
@@ -320,7 +318,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::face* face, IfcGeom::Conver
}
// @todo boundary
const auto& m = ((taxonomy::geom_item*)face->basis)->matrix.ccomponents();
const auto& m = ((taxonomy::geom_ptr)face->basis)->matrix.ccomponents();
gp_Pln pln(convert_xyz2<gp_Pnt>(m.col(3)), convert_xyz2<gp_Dir>(m.col(2)));
const gp_Pnt pnt = pln.Location().Translated(face->orientation.get_value_or(false) ? -pln.Axis().Direction() : pln.Axis().Direction());
TopoDS_Shape shape = BRepPrimAPI_MakeHalfSpace(BRepBuilderAPI_MakeFace(pln), pnt).Solid();
@@ -27,21 +27,21 @@ namespace {
IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper(
OpenCascadeKernel* kernel,
const taxonomy::shell* shell
const taxonomy::shell::ptr shell
)
: kernel_(kernel)
, non_manifold_(false)
{
// @todo use pointers?
std::vector<taxonomy::point3> points;
std::vector<taxonomy::loop*> loops;
std::vector<taxonomy::point3::ptr> points;
std::vector<taxonomy::loop::ptr> loops;
for (auto& f : shell->children_as<taxonomy::face>()) {
for (auto& l : f->children_as<taxonomy::loop>()) {
for (auto& f : shell->children) {
for (auto& l : f->children) {
loops.push_back(l);
for (auto& e : l->children_as<taxonomy::edge>()) {
for (auto& e : l->children) {
// @todo make sure only cartesian points are provided here
points.push_back(boost::get<taxonomy::point3>(e->start));
points.push_back(boost::get<taxonomy::point3::ptr>(e->start));
}
}
}
@@ -55,7 +55,7 @@ IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper(
Bnd_Box box;
for (size_t i = 0; i < points.size(); ++i) {
gp_Pnt* p = new gp_Pnt(convert_xyz<gp_Pnt>(points[i]));
gp_Pnt* p = new gp_Pnt(convert_xyz<gp_Pnt>(*points[i]));
pnts[i].reset(p);
B.MakeVertex(vertices[i], *p, Precision::Confusion());
tree.add(i, vertices[i]);
@@ -116,7 +116,7 @@ IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper(
find_neighbours(tree, pnts, vs, pnt_i, eps_);
for (int v : vs) {
auto& pt = points[v];
auto& pt = *points[v];
// NB: insert() ignores duplicate keys
// v-1?
// @todo this reliable also in case of tesselations?
@@ -192,15 +192,15 @@ IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper(
}
}
void IfcGeom::OpenCascadeKernel::faceset_helper::loop_(const taxonomy::loop* ps, const std::function<void(int, int, bool)>& callback) {
void IfcGeom::OpenCascadeKernel::faceset_helper::loop_(const taxonomy::loop::ptr ps, const std::function<void(int, int, bool)>& callback) {
if (ps->children.size() < 3) {
return;
}
auto a = boost::get<taxonomy::point3>(((taxonomy::edge*) ps->children.back())->start);
auto A = a.identity();
auto a = boost::get<taxonomy::point3::ptr>(ps->children.back()->start);
auto A = a->identity();
for (auto& b : ps->children) {
auto B = boost::get<taxonomy::point3>(((taxonomy::edge*) b)->start).identity();
auto B = boost::get<taxonomy::point3::ptr>(b->start)->identity();
auto C = vertex_mapping_[A], D = vertex_mapping_[B];
bool fwd = C < D;
if (!fwd) {
@@ -222,7 +222,7 @@ bool IfcGeom::OpenCascadeKernel::faceset_helper::edge(int A, int B, TopoDS_Edge&
return true;
}
bool IfcGeom::OpenCascadeKernel::faceset_helper::wire(const taxonomy::loop* loop, TopoDS_Wire& w) {
bool IfcGeom::OpenCascadeKernel::faceset_helper::wire(const taxonomy::loop::ptr loop, TopoDS_Wire& w) {
TopTools_ListOfShape ws;
if (!wires(loop, ws)) {
return false;
@@ -231,7 +231,7 @@ bool IfcGeom::OpenCascadeKernel::faceset_helper::wire(const taxonomy::loop* loop
return true;
}
bool IfcGeom::OpenCascadeKernel::faceset_helper::wires(const taxonomy::loop* loop, TopTools_ListOfShape& wires) {
bool IfcGeom::OpenCascadeKernel::faceset_helper::wires(const taxonomy::loop::ptr loop, TopTools_ListOfShape& wires) {
if (duplicates_.find(loop->identity()) != duplicates_.end()) {
return false;
}
+8 -8
View File
@@ -164,7 +164,7 @@ namespace {
}
bool IfcGeom::util::apply_folded_layerset(const ConversionResults& items, const std::vector< std::vector<Handle_Geom_Surface> >& surfaces, const std::vector<ifcopenshell::geometry::taxonomy::style>& styles, ConversionResults& result, double tol) {
bool IfcGeom::util::apply_folded_layerset(const ConversionResults& items, const std::vector< std::vector<Handle_Geom_Surface> >& surfaces, const std::vector<ifcopenshell::geometry::taxonomy::style::ptr>& styles, ConversionResults& result, double tol) {
Bnd_Box bb;
TopoDS_Shape input;
flatten_shape_list(items, input, false, tol);
@@ -249,8 +249,8 @@ bool IfcGeom::util::apply_folded_layerset(const ConversionResults& items, const
for (ConversionResults::const_iterator it = items.begin(); it != items.end(); ++it) {
TopoDS_Shape a, b;
if (split_solid_by_shell(((OpenCascadeShape*)it->Shape())->shape(), shells.First(), a, b, tol)) {
result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(b), &(!!styles[0].diffuse ? styles[0] : it->Style())));
result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(a), &(!!styles[1].diffuse ? styles[1] : it->Style())));
result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(b), (!!styles[0] ? styles[0] : it->StylePtr())));
result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(a), (!!styles[1] ? styles[1] : it->StylePtr())));
} else {
continue;
}
@@ -269,7 +269,7 @@ bool IfcGeom::util::apply_folded_layerset(const ConversionResults& items, const
std::vector<TopoDS_Shape> slices;
if (split(s, shells, tol, slices) && slices.size() == styles.size()) {
for (size_t i = 0; i < slices.size(); ++i) {
result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(slices[i]), &(!!styles[i].diffuse ? styles[i] : it->Style())));
result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(slices[i]), (!!styles[i] ? styles[i] : it->StylePtr())));
}
} else {
return false;
@@ -282,7 +282,7 @@ bool IfcGeom::util::apply_folded_layerset(const ConversionResults& items, const
}
bool IfcGeom::util::apply_layerset(const ConversionResults& items, const std::vector<Handle_Geom_Surface>& surfaces, const std::vector<ifcopenshell::geometry::taxonomy::style>& styles, ConversionResults& result, double tol) {
bool IfcGeom::util::apply_layerset(const ConversionResults& items, const std::vector<Handle_Geom_Surface>& surfaces, const std::vector<ifcopenshell::geometry::taxonomy::style::ptr>& styles, ConversionResults& result, double tol) {
if (surfaces.size() < 3) {
return false;
@@ -292,8 +292,8 @@ bool IfcGeom::util::apply_layerset(const ConversionResults& items, const std::ve
for (ConversionResults::const_iterator it = items.begin(); it != items.end(); ++it) {
TopoDS_Shape a, b;
if (split_solid_by_surface(((OpenCascadeShape*)it->Shape())->shape(), surfaces[1], a, b, tol)) {
result.push_back(ConversionResult(it->ItemId(), it->Placement(),new OpenCascadeShape(b), &(!!styles[0].diffuse ? styles[0] : it->Style())));
result.push_back(ConversionResult(it->ItemId(), it->Placement(),new OpenCascadeShape(a), &(!!styles[1].diffuse ? styles[1] : it->Style())));
result.push_back(ConversionResult(it->ItemId(), it->Placement(),new OpenCascadeShape(b), (!!styles[0] ? styles[0] : it->StylePtr())));
result.push_back(ConversionResult(it->ItemId(), it->Placement(),new OpenCascadeShape(a), (!!styles[1] ? styles[1] : it->StylePtr())));
} else {
continue;
}
@@ -360,7 +360,7 @@ bool IfcGeom::util::apply_layerset(const ConversionResults& items, const std::ve
std::vector<TopoDS_Shape> slices;
if (split(s, operands, tol, slices) && slices.size() == styles.size()) {
for (size_t i = 0; i < slices.size(); ++i) {
result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(slices[i]), &(!!styles[i].diffuse ? styles[i] : it->Style())));
result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(slices[i]), (!!styles[i] ? styles[i] : it->StylePtr())));
}
} else {
return false;
+2 -2
View File
@@ -11,9 +11,9 @@
namespace IfcGeom {
namespace util {
bool apply_layerset(const ConversionResults&, const std::vector<Handle_Geom_Surface>&, const std::vector<ifcopenshell::geometry::taxonomy::style>&, ConversionResults&, double tol);
bool apply_layerset(const ConversionResults&, const std::vector<Handle_Geom_Surface>&, const std::vector<ifcopenshell::geometry::taxonomy::style::ptr>&, ConversionResults&, double tol);
bool apply_folded_layerset(const ConversionResults&, const std::vector< std::vector<Handle_Geom_Surface> >&, const std::vector<ifcopenshell::geometry::taxonomy::style>&, ConversionResults&, double tol);
bool apply_folded_layerset(const ConversionResults&, const std::vector< std::vector<Handle_Geom_Surface> >&, const std::vector<ifcopenshell::geometry::taxonomy::style::ptr>&, ConversionResults&, double tol);
bool split_solid_by_surface(const TopoDS_Shape&, const Handle_Geom_Surface&, TopoDS_Shape&, TopoDS_Shape&, double tol);
+42 -44
View File
@@ -26,21 +26,21 @@ using namespace IfcGeom::util;
namespace {
typedef boost::variant<Handle(Geom_Curve), TopoDS_Wire> curve_creation_visitor_result_type;
curve_creation_visitor_result_type convert_curve(OpenCascadeKernel* kernel, const taxonomy::item* curve);
curve_creation_visitor_result_type convert_curve(OpenCascadeKernel* kernel, const taxonomy::ptr curve);
struct curve_creation_visitor {
OpenCascadeKernel* kernel;
curve_creation_visitor_result_type result;
curve_creation_visitor_result_type operator()(const taxonomy::bspline_curve& bc) {
curve_creation_visitor_result_type operator()(const taxonomy::bspline_curve::ptr& bc) {
const bool is_rational = !!bc.weights;
const bool is_rational = !!bc->weights;
TColgp_Array1OfPnt Poles(0, bc.control_points.size() - 1);
TColStd_Array1OfReal Weights(0, bc.control_points.size() - 1);
TColStd_Array1OfReal Knots(0, (int)bc.knots.size() - 1);
TColStd_Array1OfInteger Mults(0, (int)bc.knots.size() - 1);
Standard_Integer Degree = bc.degree;
TColgp_Array1OfPnt Poles(0, bc->control_points.size() - 1);
TColStd_Array1OfReal Weights(0, bc->control_points.size() - 1);
TColStd_Array1OfReal Knots(0, (int)bc->knots.size() - 1);
TColStd_Array1OfInteger Mults(0, (int)bc->knots.size() - 1);
Standard_Integer Degree = bc->degree;
Standard_Boolean Periodic = false;
// @tfk: it appears to be wrong to expect a period curve when the curve is closed, see #586
// Standard_Boolean Periodic = l->ClosedCurve();
@@ -49,23 +49,23 @@ namespace {
if (is_rational) {
i = 0;
for (auto it = bc.weights->begin(); it != bc.weights->end(); ++it, ++i) {
for (auto it = bc->weights->begin(); it != bc->weights->end(); ++it, ++i) {
Weights(i) = *it;
}
}
i = 0;
for (auto it = bc.control_points.begin(); it != bc.control_points.end(); ++it, ++i) {
Poles(i) = OpenCascadeKernel::convert_xyz<gp_Pnt>(*it);
for (auto it = bc->control_points.begin(); it != bc->control_points.end(); ++it, ++i) {
Poles(i) = OpenCascadeKernel::convert_xyz<gp_Pnt>(**it);
}
i = 0;
for (auto it = bc.multiplicities.begin(); it != bc.multiplicities.end(); ++it, ++i) {
for (auto it = bc->multiplicities.begin(); it != bc->multiplicities.end(); ++it, ++i) {
Mults(i) = *it;
}
i = 0;
for (auto it = bc.knots.begin(); it != bc.knots.end(); ++it, ++i) {
for (auto it = bc->knots.begin(); it != bc->knots.end(); ++it, ++i) {
Knots(i) = *it;
}
@@ -76,44 +76,44 @@ namespace {
}
}
curve_creation_visitor_result_type operator()(const taxonomy::line& l) {
const auto& m = l.matrix.ccomponents();
curve_creation_visitor_result_type operator()(const taxonomy::line::ptr& l) {
const auto& m = l->matrix->ccomponents();
return result = Handle(Geom_Curve)(new Geom_Line(OpenCascadeKernel::convert_xyz2<gp_Pnt>(m.col(3)), OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(0))));
}
curve_creation_visitor_result_type operator()(const taxonomy::circle& c) {
const auto& m = c.matrix.ccomponents();
return result = Handle(Geom_Curve)(new Geom_Circle(gp_Ax2(OpenCascadeKernel::convert_xyz2<gp_Pnt>(m.col(3)), OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(2)), OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(0))), c.radius));
curve_creation_visitor_result_type operator()(const taxonomy::circle::ptr& c) {
const auto& m = c->matrix->ccomponents();
return result = Handle(Geom_Curve)(new Geom_Circle(gp_Ax2(OpenCascadeKernel::convert_xyz2<gp_Pnt>(m.col(3)), OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(2)), OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(0))), c->radius));
}
curve_creation_visitor_result_type operator()(const taxonomy::ellipse& e) {
const auto& m = e.matrix.ccomponents();
return result = Handle(Geom_Curve)(new Geom_Ellipse(gp_Ax2(OpenCascadeKernel::convert_xyz2<gp_Pnt>(m.col(3)), OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(2)), OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(0))), e.radius, e.radius2));
curve_creation_visitor_result_type operator()(const taxonomy::ellipse::ptr& e) {
const auto& m = e->matrix->ccomponents();
return result = Handle(Geom_Curve)(new Geom_Ellipse(gp_Ax2(OpenCascadeKernel::convert_xyz2<gp_Pnt>(m.col(3)), OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(2)), OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(0))), e->radius, e->radius2));
}
curve_creation_visitor_result_type operator()(const taxonomy::loop& l) {
curve_creation_visitor_result_type operator()(const taxonomy::loop::ptr& l) {
TopoDS_Wire wire;
kernel->convert(&l, wire);
kernel->convert(l, wire);
return result = wire;
}
curve_creation_visitor_result_type operator()(const taxonomy::edge& e) {
curve_creation_visitor_result_type operator()(const taxonomy::edge::ptr& e) {
// @todo for polyloops/-lines we should probably construct edges based on correct oriented TopoDS_Vertex instead.
if (e.start.which() != e.end.which()) {
if (e->start.which() != e->end.which()) {
throw std::runtime_error("Different trim types not supported");
}
TopoDS_Edge E;
if (e.basis) {
auto crv_or_wire = convert_curve(kernel, e.basis);
if (e->basis) {
auto crv_or_wire = convert_curve(kernel, e->basis);
Handle(Geom_Curve) curve;
if (crv_or_wire.which() == 0) {
curve = boost::get<Handle(Geom_Curve)>(crv_or_wire);
} else {
// @todo
const double precision_ = 1.e-5;
Logger::Warning("Approximating BasisCurve due to possible discontinuities", e.instance);
Logger::Warning("Approximating BasisCurve due to possible discontinuities", e->instance);
const auto& w = boost::get<TopoDS_Wire>(crv_or_wire);
#if OCC_VERSION_HEX < 0x70600
BRepAdaptor_CompCurve cc(w, true);
@@ -126,13 +126,13 @@ namespace {
curve = approx.Curve();
}
const bool reversed = !((taxonomy::geom_item*)e.basis)->orientation.get_value_or(true);
const bool is_conic = e.basis->kind() == taxonomy::ELLIPSE || e.basis->kind() == taxonomy::CIRCLE;
const bool reversed = !taxonomy::cast<taxonomy::geom_item>(e->basis)->orientation.get_value_or(true);
const bool is_conic = e->basis->kind() == taxonomy::ELLIPSE || e->basis->kind() == taxonomy::CIRCLE;
// @todo, copy over logic from previous IfcTrimmedCurve handling
if (e.start.which() == 0) {
auto p1 = OpenCascadeKernel::convert_xyz<gp_Pnt>(boost::get<taxonomy::point3>(e.start));
auto p2 = OpenCascadeKernel::convert_xyz<gp_Pnt>(boost::get<taxonomy::point3>(e.end));
if (e->start.which() == 0) {
auto p1 = OpenCascadeKernel::convert_xyz<gp_Pnt>(*boost::get<taxonomy::point3::ptr>(e->start));
auto p2 = OpenCascadeKernel::convert_xyz<gp_Pnt>(*boost::get<taxonomy::point3::ptr>(e->end));
if (reversed) {
std::swap(p1, p2);
@@ -140,8 +140,8 @@ namespace {
E = BRepBuilderAPI_MakeEdge(curve, p1, p2).Edge();
} else {
auto v1 = boost::get<double>(e.start);
auto v2 = boost::get<double>(e.end);
auto v1 = boost::get<double>(e->start);
auto v2 = boost::get<double>(e->end);
if (reversed) {
std::swap(v1, v2);
@@ -158,11 +158,11 @@ namespace {
E.Reverse();
}
} else {
if (e.start.which() != 0) {
if (e->start.which() != 0) {
throw std::runtime_error("Non-cartesian trim on edge without curve");
}
auto p1 = OpenCascadeKernel::convert_xyz<gp_Pnt>(boost::get<taxonomy::point3>(e.start));
auto p2 = OpenCascadeKernel::convert_xyz<gp_Pnt>(boost::get<taxonomy::point3>(e.end));
auto p1 = OpenCascadeKernel::convert_xyz<gp_Pnt>(*boost::get<taxonomy::point3::ptr>(e->start));
auto p2 = OpenCascadeKernel::convert_xyz<gp_Pnt>(*boost::get<taxonomy::point3::ptr>(e->end));
E = BRepBuilderAPI_MakeEdge(p1, p2).Edge();
}
@@ -173,13 +173,13 @@ namespace {
return result = W;
}
curve_creation_visitor_result_type operator()(const taxonomy::offset_curve& l) {
curve_creation_visitor_result_type operator()(const taxonomy::offset_curve::ptr&) {
// @todo
throw std::runtime_error("Offset curves not supported as part of loop");
}
};
curve_creation_visitor_result_type convert_curve(OpenCascadeKernel* kernel, const taxonomy::item* curve) {
curve_creation_visitor_result_type convert_curve(OpenCascadeKernel* kernel, const taxonomy::ptr curve) {
curve_creation_visitor v{ kernel };
if (dispatch_curve_creation<curve_creation_visitor, 0>::dispatch(curve, v)) {
return v.result;
@@ -189,12 +189,10 @@ namespace {
}
}
bool OpenCascadeKernel::convert(const taxonomy::loop* loop, TopoDS_Wire& wire) {
auto segments = loop->children_as<taxonomy::edge>();
bool OpenCascadeKernel::convert(const taxonomy::loop::ptr loop, TopoDS_Wire& wire) {
TopTools_ListOfShape converted_segments;
for (auto& segment : segments) {
for (auto& segment : loop->children) {
auto segment_wire = boost::get<TopoDS_Wire>(convert_curve(this, segment));
#ifdef IFOPSH_DEBUG
+1 -1
View File
@@ -5,7 +5,7 @@ using namespace ifcopenshell::geometry::kernels;
using namespace IfcGeom;
using namespace IfcGeom::util;
bool OpenCascadeKernel::convert(const taxonomy::matrix4* matrix, gp_GTrsf& trsf) {
bool OpenCascadeKernel::convert(const taxonomy::matrix4::ptr matrix, gp_GTrsf& trsf) {
// @todo check
const auto& m = matrix->ccomponents();
gp_Mat mat(
+3 -4
View File
@@ -7,13 +7,12 @@ using namespace ifcopenshell::geometry::kernels;
using namespace IfcGeom;
using namespace IfcGeom::util;
bool OpenCascadeKernel::convert(const taxonomy::shell* l, TopoDS_Shape& shape) {
bool OpenCascadeKernel::convert(const taxonomy::shell::ptr l, TopoDS_Shape& shape) {
std::unique_ptr<faceset_helper> helper_scope;
helper_scope.reset(new faceset_helper(this, l));
faceset_helper_ = helper_scope.get();
auto faces = l->children_as<taxonomy::face>();
double minimal_face_area = precision_ * precision_ * 0.5;
double min_face_area = faceset_helper_
@@ -21,7 +20,7 @@ bool OpenCascadeKernel::convert(const taxonomy::shell* l, TopoDS_Shape& shape) {
: minimal_face_area;
TopTools_ListOfShape face_list;
for (auto& face : faces) {
for (auto& face : l->children) {
bool success = false;
TopoDS_Face occ_face;
@@ -88,7 +87,7 @@ bool OpenCascadeKernel::convert(const taxonomy::shell* l, TopoDS_Shape& shape) {
return true;
}
bool OpenCascadeKernel::convert_impl(const taxonomy::shell *shell, IfcGeom::ConversionResults& results) {
bool OpenCascadeKernel::convert_impl(const taxonomy::shell::ptr shell, IfcGeom::ConversionResults& results) {
TopoDS_Shape shape;
if (!convert(shell, shape)) {
return false;
+41 -43
View File
@@ -29,59 +29,57 @@ using namespace ifcopenshell::geometry::kernels;
using namespace IfcGeom;
using namespace IfcGeom::util;
bool OpenCascadeKernel::convert(const taxonomy::solid* solid, TopoDS_Shape& result) {
bool OpenCascadeKernel::convert(const taxonomy::solid::ptr solid, TopoDS_Shape& result) {
BRep_Builder BB;
TopoDS_Solid S;
for (auto& s : solid->children) {
if (s->kind() == taxonomy::FACE) {
// halfspace
if (solid->children.size() != 1) {
throw std::runtime_error("Unexpected number of children on solid");
}
auto face = (taxonomy::face*) s;
const auto& m = ((taxonomy::geom_item*)face->basis)->matrix.ccomponents();
gp_Pln pln(convert_xyz2<gp_Pnt>(m.col(3)), convert_xyz2<gp_Dir>(m.col(2)));
const gp_Pnt pnt = pln.Location().Translated(face->orientation.get_value_or(false) ? pln.Axis().Direction() : -pln.Axis().Direction());
TopoDS_Shape halfspace = BRepPrimAPI_MakeHalfSpace(BRepBuilderAPI_MakeFace(pln), pnt).Solid();
if (!face->children.empty()) {
TopoDS_Wire wire;
gp_GTrsf gtrsf;
if (convert((taxonomy::loop*)face->children[0], wire) && wire.Closed() && convert(&face->matrix, gtrsf)) {
gp_Trsf trsf = gtrsf.Trsf();
TopoDS_Shape prism = BRepPrimAPI_MakePrism(BRepBuilderAPI_MakeFace(wire), gp_Vec(0, 0, 200));
gp_Trsf down; down.SetTranslation(gp_Vec(0, 0, -100.0));
// `trsf` and `down` both have a unit scale factor
prism.Move(trsf*down);
halfspace = BRepAlgoAPI_Common(halfspace, prism);
}
}
result = halfspace;
return true;
} else {
if (s->kind() != taxonomy::SHELL) {
throw std::runtime_error("Unexpected child in solid");
}
if (S.IsNull()) {
BB.MakeSolid(S);
}
TopoDS_Shell shl;
convert(((taxonomy::shell*)s), shl);
BB.Add(S, shl);
if (solid->instance->declaration().is("IfcHalfSpaceSolid")) {
// halfspace
if (solid->children.size() != 1) {
throw std::runtime_error("Unexpected number of children on solid");
}
auto face = solid->children[0]->children[0];
const auto& m = taxonomy::cast<taxonomy::plane>(face->basis)->matrix->ccomponents();
gp_Pln pln(convert_xyz2<gp_Pnt>(m.col(3)), convert_xyz2<gp_Dir>(m.col(2)));
const gp_Pnt pnt = pln.Location().Translated(face->orientation.get_value_or(false) ? pln.Axis().Direction() : -pln.Axis().Direction());
TopoDS_Shape halfspace = BRepPrimAPI_MakeHalfSpace(BRepBuilderAPI_MakeFace(pln), pnt).Solid();
if (!face->children.empty()) {
TopoDS_Wire wire;
gp_GTrsf gtrsf;
if (convert((taxonomy::loop::ptr)face->children[0], wire) && wire.Closed() && convert(face->matrix, gtrsf)) {
gp_Trsf trsf = gtrsf.Trsf();
TopoDS_Shape prism = BRepPrimAPI_MakePrism(BRepBuilderAPI_MakeFace(wire), gp_Vec(0, 0, 200));
gp_Trsf down; down.SetTranslation(gp_Vec(0, 0, -100.0));
// `trsf` and `down` both have a unit scale factor
prism.Move(trsf*down);
halfspace = BRepAlgoAPI_Common(halfspace, prism);
}
}
result = halfspace;
return true;
}
for (auto& s : solid->children) {
if (S.IsNull()) {
BB.MakeSolid(S);
}
TopoDS_Shell shl;
convert(((taxonomy::shell::ptr)s), shl);
BB.Add(S, shl);
}
if (!S.IsNull()) {
result = S;
}
}
bool OpenCascadeKernel::convert_impl(const taxonomy::solid* solid , IfcGeom::ConversionResults& results) {
bool OpenCascadeKernel::convert_impl(const taxonomy::solid::ptr solid , IfcGeom::ConversionResults& results) {
TopoDS_Shape shape;
if (!convert(solid, shape)) {
return false;