Work towards v1.0 data model with encapsulated weak_ptr as basis for instances

This commit is contained in:
Thomas Krijnen
2026-01-04 10:40:02 +01:00
parent f09ca658f1
commit 7098beb819
210 changed files with 28269 additions and 26471 deletions
@@ -223,7 +223,7 @@ void ifcopenshell::geometry::CgalShape::Triangulate(ifcopenshell::geometry::Sett
}
}
boost::optional<double> smooth_treshold;
std::optional<double> smooth_treshold;
{
auto setting_value = settings.get<ifcopenshell::geometry::settings::CgalSmoothAngleDegrees>().get();
if (setting_value > 0.) {
@@ -180,9 +180,9 @@ namespace ifcopenshell { namespace geometry {
class IFC_GEOMLIBRARY_API CgalShape : public IfcGeom::ConversionResultShape {
private:
bool convex_tag_ = false;
mutable boost::optional<cgal_shape_t> shape_;
mutable std::optional<cgal_shape_t> shape_;
#ifndef IFOPSH_SIMPLE_KERNEL
mutable boost::optional<CGAL::Nef_polyhedron_3<Kernel_>> nef_;
mutable std::optional<CGAL::Nef_polyhedron_3<Kernel_>> nef_;
#endif
public:
CgalShape(const cgal_shape_t& shape, bool convex = false);
+32 -32
View File
@@ -47,7 +47,7 @@ namespace {
private:
std::list<cgal_face_t> *face_list;
public:
boost::optional<cgal_shape_t> from_soup;
std::optional<cgal_shape_t> from_soup;
PolyhedronBuilder(std::list<cgal_face_t> *face_list);
void operator()(CGAL::Polyhedron_3<Kernel_>::HalfedgeDS &hds);
};
@@ -232,7 +232,7 @@ bool CgalKernel::convert(const taxonomy::face::ptr face, std::list<cgal_face_t>&
int num_outer_bounds = 0;
for (auto& bound : face->children) {
if (bound->external.get_value_or(false)) num_outer_bounds++;
if (bound->external.value_or(false)) num_outer_bounds++;
}
if (face->children.size() > 1 && num_outer_bounds > 1 && face->children.size() != num_outer_bounds) {
@@ -244,7 +244,7 @@ bool CgalKernel::convert(const taxonomy::face::ptr face, std::list<cgal_face_t>&
for (auto& bound : face->children) {
const bool is_interior = !(bound->external.get_value_or(false) || face->children.size() == 1);
const bool is_interior = !(bound->external.value_or(false) || face->children.size() == 1);
// single face bound is always external... even if not marked as such
cgal_wire_t wire;
@@ -284,11 +284,11 @@ namespace {
if (auto e = taxonomy::dcast<taxonomy::edge>(curve)) {
if (true || e->basis == nullptr) {
if (builder.empty()) {
const auto& p = boost::get<taxonomy::point3::ptr>(e->start);
const auto& p = std::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::ptr>(e->end);
const auto& p = std::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) {
@@ -450,17 +450,17 @@ namespace {
void operator()(const taxonomy::trimmed_curve::ptr& e) {
auto e_basis = e->basis;
while (e_basis->kind() == taxonomy::EDGE && e_basis->instance && e_basis->instance->declaration().name() == "IfcTrimmedCurve") {
while (e_basis->kind() == taxonomy::EDGE && e_basis->instance && e_basis->instance.declaration().name() == "IfcTrimmedCurve") {
// @todo we still might have something to wrt orientation on periodic curves
// to make sure we select the correct arc later on.
e_basis = taxonomy::cast<taxonomy::edge>(e_basis)->basis;
}
point_projection_visitor v1{ e->basis }, v2{ e->basis };
boost::apply_visitor(v1, e->start);
boost::apply_visitor(v2, e->end);
std::visit(v1, e->start);
std::visit(v2, e->end);
if (!e->curve_sense.get_value_or(true)) {
if (!e->curve_sense.value_or(true)) {
std::swap(v1.u, v2.u);
}
@@ -469,7 +469,7 @@ namespace {
dispatch_curve_creation<cgal_curve_creation_visitor>::dispatch(e->basis, v);
this->points = v.points;
if (!e->curve_sense.get_value_or(true)) {
if (!e->curve_sense.value_or(true)) {
std::reverse(this->points.begin(), this->points.end());
}
}
@@ -581,7 +581,7 @@ namespace {
CGAL::Polygon_2<Kernel_> loop_to_polygon_2(taxonomy::loop::ptr loop) {
CGAL::Polygon_2<Kernel_> polygon;
for (auto& e : loop->children) {
auto& p = *boost::get<taxonomy::point3::ptr>(e->start);
auto& p = *std::get<taxonomy::point3::ptr>(e->start);
CGAL::Point_2<Kernel_> pnt(p.ccomponents()(0), p.ccomponents()(1));
polygon.push_back(pnt);
}
@@ -685,12 +685,12 @@ bool CgalKernel::convert(const taxonomy::loop::ptr loop, cgal_wire_t& result) {
convert_curve(settings_, e, edge);
} else {
edge = {
*boost::get<taxonomy::point3::ptr>(e->start),
*boost::get<taxonomy::point3::ptr>(e->end)
*std::get<taxonomy::point3::ptr>(e->start),
*std::get<taxonomy::point3::ptr>(e->end)
};
}
if (!e->orientation.get_value_or(true)) {
if (!e->orientation.value_or(true)) {
std::reverse(edge.begin(), edge.end());
}
@@ -809,7 +809,7 @@ bool CgalKernel::convert_impl(const taxonomy::shell::ptr shell, ConversionResult
return false;
}
results.emplace_back(ConversionResult(
shell->instance->as<IfcUtil::IfcBaseEntity>()->id(),
shell->instance.id(),
shell->matrix,
new CgalShape(shape),
shell->surface_style
@@ -834,7 +834,7 @@ bool CgalKernel::convert_impl(const taxonomy::solid::ptr solid, ConversionResult
return false;
}
results.emplace_back(ConversionResult(
solid->instance->as<IfcUtil::IfcBaseEntity>()->id(),
solid->instance.id(),
solid->matrix,
new CgalShape(shape),
solid->surface_style
@@ -857,7 +857,7 @@ namespace {
}
}
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)
bool ifcopenshell::geometry::kernels::CgalKernel::convert_openings(const express::Base& 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;
@@ -865,9 +865,9 @@ bool ifcopenshell::geometry::kernels::CgalKernel::convert_openings(const IfcUtil
CGAL::Nef_nary_union_3<CGAL::Nef_polyhedron_3<Kernel_>> second_operand_collector;
size_t second_operand_collector_size = 0;
std::list<std::pair<const IfcUtil::IfcBaseClass*, std::list<cgal_shape_t>>> operands;
std::list<std::pair<express::Base, std::list<cgal_shape_t>>> operands;
std::list<const IfcUtil::IfcBaseClass*> second_operand_instances;
std::list<express::Base> second_operand_instances;
std::list<cgal_shape_t> first_operands, second_operands;
std::list<CGAL::Nef_polyhedron_3<Kernel_>> first_operands_nef, second_operands_nef;
@@ -916,13 +916,13 @@ bool ifcopenshell::geometry::kernels::CgalKernel::convert_openings(const IfcUtil
}
}
CGAL::Nef_polyhedron_3<Kernel_> nef;
if (!preprocess_boolean_operand(op.first->instance->as<IfcUtil::IfcBaseClass>(), {}, {}, {}, entity_shape, nef, PP_NONE)) {
if (!preprocess_boolean_operand(op.first->instance, {}, {}, {}, entity_shape, nef, PP_NONE)) {
continue;
}
// auto tree = build_halfspace_tree_decomposed(nef, all_operand_planes);
second_operand_instances.push_back(op.first->instance->as<IfcUtil::IfcBaseClass>());
second_operand_instances.push_back(op.first->instance);
second_operands.push_back(entity_shape);
second_operands_nef.push_back(nef);
}
@@ -984,7 +984,7 @@ bool CgalKernel::convert_impl(const taxonomy::extrusion::ptr extrusion, Conversi
return false;
}
results.emplace_back(ConversionResult(
extrusion->instance->as<IfcUtil::IfcBaseEntity>()->id(),
extrusion->instance.id(),
extrusion->matrix,
new CgalShape(shape),
extrusion->surface_style
@@ -1321,7 +1321,7 @@ bool CgalKernel::thin_solid(const CGAL::Nef_polyhedron_3<Kernel_>& a, CGAL::Nef_
return true;
}
bool CgalKernel::preprocess_boolean_operand(const IfcUtil::IfcBaseClass* log_reference, const std::list<cgal_shape_t>& first_operands, const std::list<CGAL::Nef_polyhedron_3<Kernel_>>& first_operands_nef, const std::list<Kernel_::Plane_3>& all_operand_planes, const cgal_shape_t& shape_const, CGAL::Nef_polyhedron_3<Kernel_>& result, boolean_operand_preprocess proc) {
bool CgalKernel::preprocess_boolean_operand(const express::Base& log_reference, const std::list<cgal_shape_t>& first_operands, const std::list<CGAL::Nef_polyhedron_3<Kernel_>>& first_operands_nef, const std::list<Kernel_::Plane_3>& all_operand_planes, const cgal_shape_t& shape_const, CGAL::Nef_polyhedron_3<Kernel_>& result, boolean_operand_preprocess proc) {
cgal_shape_t shape = shape_const;
if (!shape.is_valid()) {
@@ -1727,7 +1727,7 @@ namespace {
}
}
bool CgalKernel::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) {
bool CgalKernel::process_as_2d_polygon(const std::list<std::list<std::pair<express::Base, cgal_shape_t>>>& operands, std::list<CGAL::Polygon_2<Kernel_>>& loops, double& z0, double& z1) {
if (operands.front().size() != 1) {
return false;
}
@@ -1887,7 +1887,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result::ptr br, Conversion
}
return ConversionResult(
br->instance->as<IfcUtil::IfcBaseEntity>()->id(),
br->instance.id(),
br->matrix,
new CgalShape(shp),
br->surface_style ? br->surface_style : first_item_style
@@ -1912,7 +1912,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result::ptr br, Conversion
taxonomy::style::ptr first_item_style = nullptr;
std::list<std::pair<const IfcUtil::IfcBaseClass*, std::list<cgal_shape_t>>> operands;
std::list<std::pair<express::Base, std::list<cgal_shape_t>>> operands;
for (auto& c : br->children) {
// AbstractKernel::convert(c, results);
@@ -1921,9 +1921,9 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result::ptr br, Conversion
ConversionResults cr;
operands.emplace_back();
operands.back().first = c->instance->as<IfcUtil::IfcBaseClass>();
operands.back().first = c->instance;
if (c->kind() == taxonomy::SOLID && c->instance->declaration().is("IfcHalfSpaceSolid") && !first) {
if (c->kind() == taxonomy::SOLID && c->instance.declaration().is("IfcHalfSpaceSolid") && !first) {
auto face = taxonomy::cast<taxonomy::solid>(c)->children[0]->children[0];
if (face->basis == nullptr || face->basis->kind() != taxonomy::PLANE) {
@@ -1951,7 +1951,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result::ptr br, Conversion
});
double wmin, wmax;
if (face->orientation.get_value_or(false)) {
if (face->orientation.value_or(false)) {
wmin = 0.;
wmax = uvw_max[2] + eps;
} else {
@@ -2043,7 +2043,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result::ptr br, Conversion
for (auto& li : operands) {
for (auto& s : li.second) {
results.emplace_back(ConversionResult(
br->instance->data().id(),
br->instance.data().id(),
br->matrix,
new CgalShape(s),
br->surface_style ? br->surface_style : first_item_style
@@ -2065,7 +2065,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result::ptr br, Conversion
for (auto& p : operands) {
for (auto& s : p.second) {
results.emplace_back(ConversionResult(
br->instance->data().id(),
br->instance.data().id(),
br->matrix,
new CgalShape(s),
br->surface_style ? br->surface_style : first_item_style
@@ -2131,7 +2131,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result::ptr br, Conversion
}
results.emplace_back(ConversionResult(
br->instance->as<IfcUtil::IfcBaseEntity>()->id(),
br->instance.id(),
br->matrix,
new CgalShape(a_poly),
br->surface_style ? br->surface_style : first_item_style
+3 -3
View File
@@ -80,7 +80,7 @@ namespace ifcopenshell {
PP_NONE
};
bool preprocess_boolean_operand(const IfcUtil::IfcBaseClass* log_reference, const std::list<cgal_shape_t>& first_operands, const std::list<CGAL::Nef_polyhedron_3<Kernel_>>& first_operands_nef, const std::list<Kernel_::Plane_3>& all_operand_planes, const cgal_shape_t& shape_const, CGAL::Nef_polyhedron_3<Kernel_>& result, boolean_operand_preprocess proc);
bool preprocess_boolean_operand(const express::Base& log_reference, const std::list<cgal_shape_t>& first_operands, const std::list<CGAL::Nef_polyhedron_3<Kernel_>>& first_operands_nef, const std::list<Kernel_::Plane_3>& all_operand_planes, const cgal_shape_t& shape_const, CGAL::Nef_polyhedron_3<Kernel_>& result, boolean_operand_preprocess proc);
bool thin_solid(const CGAL::Nef_polyhedron_3<Kernel_>& a, CGAL::Nef_polyhedron_3<Kernel_>& result);
@@ -115,14 +115,14 @@ namespace ifcopenshell {
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);
bool process_as_2d_polygon(const std::list<std::list<std::pair<express::Base, cgal_shape_t>>>& operands, std::list<CGAL::Polygon_2<Kernel_>>& loops, double& z0, double& z1);
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::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
virtual bool convert_openings(const express::Base& 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
@@ -621,7 +621,7 @@ struct Intersection_visitor {
template <typename Kernel>
struct Segment_collector {
typedef void result_type;
boost::optional<CGAL::Segment_3<Kernel>> segment;
std::optional<CGAL::Segment_3<Kernel>> segment;
void operator()(const CGAL::Point_3<Kernel>&)
{
@@ -648,7 +648,7 @@ public:
template <typename Edge, typename Graph>
bool tree_edge(Edge e, const Graph& g) {
if (boost::get(boost::edge_weight, g, e) == edgetype_) {
if (std::get(boost::edge_weight, g, e) == edgetype_) {
auto srcid = boost::source(e, g);
auto tgtid = boost::target(e, g);
@@ -667,7 +667,7 @@ public:
typename boost::graph_traits<Graph>::out_edge_iterator ei, ei_end;
for (boost::tie(ei, ei_end) = boost::out_edges(tgtid, g); ei != ei_end; ++ei) {
if (boost::get(boost::edge_weight, g, *ei) != edgetype_) {
if (std::get(boost::edge_weight, g, *ei) != edgetype_) {
tgt_has_any_reflex_edge = true;
// std::cout << " reflex: " << boost::source(*ei, g) << " -- " << boost::target(*ei, g) << std::endl;
break;
@@ -712,9 +712,9 @@ public:
if (x) {
// std::cout << " triangle: " << t << std::endl;
// Intersection_visitor v;
// boost::apply_visitor([](auto x) {std::cout << " intersects: " << x << std::endl; })(*x);
// std::visit([](auto x) {std::cout << " intersects: " << x << std::endl; })(*x);
Segment_collector<Kernel> sc;
boost::apply_visitor(sc)(*x);
std::visit(sc)(*x);
if (sc.segment) {
if (!std::any_of(edges_i.begin(), edges_i.end(), [&sc](CGAL::Segment_3<Kernel>& s) {
// When intersecting with the boundary of a facet we likely multiple co-planar facets. Exclude intersection.
@@ -723,7 +723,7 @@ public:
return false;
}
Segment_collector<Kernel> scy;
boost::apply_visitor(scy)(*xy);
std::visit(scy)(*xy);
return (bool)scy.segment;
})) {
return true;
@@ -807,7 +807,7 @@ std::unique_ptr<halfspace_tree<TreeKernel>> build_halfspace_tree(Graph<Kernel>&
bool all_convex = true;
typename boost::graph_traits<Graph<Kernel>>::edge_iterator ei, ei_end;
for (boost::tie(ei, ei_end) = boost::edges(G); ei != ei_end; ++ei) {
if (boost::get(boost::edge_weight, G, *ei) != edge_trait) {
if (std::get(boost::edge_weight, G, *ei) != edge_trait) {
// all_convex = false;
break;
}
@@ -1030,7 +1030,7 @@ public:
auto verts_backup = verts;
auto facets_backup = facets;
boost::optional<CGAL::Polygon_with_holes_2<Kernel>> pwh;
std::optional<CGAL::Polygon_with_holes_2<Kernel>> pwh;
auto nf = std::distance(h->facet_cycles_begin(), h->facet_cycles_end());
for (auto fc = h->facet_cycles_begin(); fc != h->facet_cycles_end(); ++fc) {
// std::cout << "h_plane.point() " << h_plane.point() << std::endl;