Skip to content

Commit 7098beb

Browse files
committed
Work towards v1.0 data model with encapsulated weak_ptr as basis for instances
1 parent f09ca65 commit 7098beb

210 files changed

Lines changed: 28392 additions & 26594 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/examples/IfcAlignment.cpp

Lines changed: 394 additions & 449 deletions
Large diffs are not rendered by default.

src/ifcconvert/IfcConvert.cpp

Lines changed: 45 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
#endif
6262

6363
#include <boost/program_options.hpp>
64+
#include <boost/optional/optional_io.hpp>
6465
#include <boost/make_shared.hpp>
6566

6667
#include <fstream>
@@ -202,7 +203,7 @@ struct exclusion_traverse_filter : public geom_filter { exclusion_traverse_filte
202203

203204
size_t read_filters_from_file(const std::string&, inclusion_filter&, inclusion_traverse_filter&, exclusion_filter&, exclusion_traverse_filter&);
204205
void parse_filter(geom_filter &, const std::vector<std::string>&);
205-
std::vector<IfcGeom::filter_t> setup_filters(const std::vector<geom_filter>&, const std::string&);
206+
std::vector<ifcopenshell::geometry::filter_t> setup_filters(const std::vector<geom_filter>&, const std::string&);
206207

207208
bool init_input_file(const std::string& filename, IfcParse::IfcFile*& ifc_file, bool no_progress, bool mmap, bool bypass_properties=false);
208209

@@ -755,7 +756,7 @@ int main(int argc, char** argv) {
755756
if (exclude_filter.type != geom_filter::UNUSED) { used_filters.push_back(exclude_filter); }
756757
if (exclude_traverse_filter.type != geom_filter::UNUSED) { used_filters.push_back(exclude_traverse_filter); }
757758

758-
std::vector<IfcGeom::filter_t> filter_funcs = setup_filters(used_filters, IfcUtil::path::to_utf8(output_extension));
759+
std::vector<ifcopenshell::geometry::filter_t> filter_funcs = setup_filters(used_filters, IfcUtil::path::to_utf8(output_extension));
759760
if (filter_funcs.empty()) {
760761
cerr_ << "[Error] Failed to set up geometry filters\n";
761762
return EXIT_FAILURE;
@@ -1277,9 +1278,9 @@ bool init_input_file(const std::string& filename, IfcParse::IfcFile*& ifc_file,
12771278
bool requires_init = false;
12781279

12791280
#ifdef WITH_IFCXML
1280-
if (boost::ends_with(boost::to_lower_copy(filename), ".ifcxml")) {
1281-
ifc_file = IfcParse::parse_ifcxml(filename);
1282-
} else
1281+
// if (boost::ends_with(boost::to_lower_copy(filename), ".ifcxml")) {
1282+
// ifc_file = IfcParse::parse_ifcxml(filename);
1283+
// } else
12831284
#endif
12841285
{
12851286
ifc_file = new IfcParse::IfcFile(IfcParse::uninitialized_tag{});
@@ -1451,9 +1452,9 @@ void validate(boost::any& v, const std::vector<std::string>& values, exclusion_t
14511452

14521453
/// @todo Clean up this filter initialization code further.
14531454
/// @return References to the used filter functors, if none an error occurred.
1454-
std::vector<IfcGeom::filter_t> setup_filters(const std::vector<geom_filter>& filters, const std::string& output_extension)
1455+
std::vector<ifcopenshell::geometry::filter_t> setup_filters(const std::vector<geom_filter>& filters, const std::string& output_extension)
14551456
{
1456-
std::vector<IfcGeom::filter_t> filter_funcs;
1457+
std::vector<ifcopenshell::geometry::filter_t> filter_funcs;
14571458
for(auto& f: filters) {
14581459
if (f.type == geom_filter::ENTITY_TYPE) {
14591460
entity_filter.include = f.include;
@@ -1493,13 +1494,13 @@ std::vector<IfcGeom::filter_t> setup_filters(const std::vector<geom_filter>& fil
14931494
namespace latebound_access {
14941495

14951496
template <typename T>
1496-
void set(IfcUtil::IfcBaseClass* inst, const std::string& attr, T t);
1497+
void set(express::Base inst, const std::string& attr, T t);
14971498

14981499
template <typename T>
1499-
void set_enumeration(IfcUtil::IfcBaseClass*, const std::string&, const IfcParse::enumeration_type*, T) {}
1500+
void set_enumeration(express::Base, const std::string&, const IfcParse::enumeration_type*, T) {}
15001501

15011502
template <>
1502-
void set_enumeration(IfcUtil::IfcBaseClass* inst, const std::string& attr, const IfcParse::enumeration_type* enum_type, std::string t) {
1503+
void set_enumeration(express::Base inst, const std::string& attr, const IfcParse::enumeration_type* enum_type, std::string t) {
15031504
std::vector<std::string>::const_iterator it = std::find(
15041505
enum_type->enumeration_items().begin(),
15051506
enum_type->enumeration_items().end(),
@@ -1509,71 +1510,61 @@ namespace latebound_access {
15091510
}
15101511

15111512
template <typename T>
1512-
void set(IfcUtil::IfcBaseClass* inst, const std::string& attr, T t) {
1513-
auto decl = inst->declaration().as_entity();
1513+
void set(express::Base inst, const std::string& attr, T t) {
1514+
auto decl = inst.declaration().as_entity();
15141515
auto i = decl->attribute_index(attr);
15151516

15161517
auto attr_type = decl->attribute_by_index(i)->type_of_attribute();
15171518
if (attr_type->as_named_type() && attr_type->as_named_type()->declared_type()->as_enumeration_type() && !std::is_same<T, EnumerationReference>::value) {
15181519
set_enumeration(inst, attr, attr_type->as_named_type()->declared_type()->as_enumeration_type(), t);
15191520
} else {
1520-
inst->set_attribute_value(i, t);
1521+
inst.set_attribute_value(i, t);
15211522
}
15221523
}
15231524

1524-
IfcUtil::IfcBaseClass* create(IfcParse::IfcFile& f, const std::string& entity) {
1525+
express::Base create(IfcParse::IfcFile& f, const std::string& entity) {
15251526
auto decl = f.schema()->declaration_by_name(entity);
1526-
auto data = IfcEntityInstanceData(in_memory_attribute_storage(decl->as_entity()->attribute_count()));
1527-
auto inst = f.schema()->instantiate(decl, std::move(data));
1528-
if (decl->is("IfcRoot")) {
1529-
IfcParse::IfcGlobalId guid;
1530-
latebound_access::set(inst, "GlobalId", (std::string) guid);
1531-
}
1532-
return f.addEntity(inst);
1527+
return f.create(decl);
15331528
}
15341529
}
15351530

15361531
void fix_quantities(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool stderr_progress) {
15371532
{
1538-
auto delete_reversed = [&f](const aggregate_of_instance::ptr& insts) {
1539-
if (!insts) {
1540-
return;
1541-
}
1533+
auto delete_reversed = [&f](const std::vector<express::Base>& insts) {
15421534
// Lists are traversed back to front as the list may be mutated when
15431535
// instances are removed from the grouping by type.
1544-
for (auto it = insts->end() - 1; it >= insts->begin(); --it) {
1545-
IfcUtil::IfcBaseClass* const inst = *it;
1546-
f.removeEntity(inst);
1536+
for (auto it = insts.end() - 1; it >= insts.begin(); --it) {
1537+
f.removeEntity(*it);
15471538
}
15481539
};
15491540

15501541
// Delete quantities
15511542
auto quantities = f.instances_by_type("IfcPhysicalQuantity");
1552-
if (quantities) {
1553-
quantities = quantities->filtered({ f.schema()->declaration_by_name("IfcPhysicalComplexQuantity") });
1554-
delete_reversed(quantities);
1555-
}
1543+
for (auto it = quantities.end() - 1; it >= quantities.begin(); --it) {
1544+
if (!it->declaration().is("IfcPhysicalComplexQuantity")) {
1545+
f.removeEntity(*it);
1546+
}
1547+
}
15561548

15571549
// Delete complexes
15581550
delete_reversed(f.instances_by_type("IfcPhysicalComplexQuantity"));
15591551

15601552
auto element_quantities = f.instances_by_type("IfcElementQuantity");
15611553

15621554
// Capture relationship nodes
1563-
std::vector<IfcUtil::IfcBaseClass*> relationships;
1555+
std::vector<express::Entity> relationships;
15641556
auto IfcRelDefinesByProperties = f.schema()->declaration_by_name("IfcRelDefinesByProperties");
1565-
if (element_quantities) {
1566-
for (auto& eq : *element_quantities) {
1567-
auto rels = eq->file_->getInverse(eq->id(), IfcRelDefinesByProperties, -1);
1568-
for (auto& rel : *rels) {
1569-
relationships.push_back(rel);
1570-
}
1571-
}
15721557

1573-
// Delete element quantities
1574-
delete_reversed(element_quantities);
1558+
for (auto& eq : element_quantities) {
1559+
auto rels = eq.data()->file()->getInverse(eq.id(), IfcRelDefinesByProperties, -1);
1560+
for (auto& rel : rels) {
1561+
relationships.push_back(rel);
1562+
}
15751563
}
15761564

1565+
// Delete element quantities
1566+
delete_reversed(element_quantities);
1567+
15771568

15781569
// Delete relationship nodes
15791570
for (auto& rel : relationships) {
@@ -1620,8 +1611,8 @@ void fix_quantities(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool std
16201611
latebound_access::set(ownerhist, "ChangeAction", std::string("MODIFIED"));
16211612
latebound_access::set(ownerhist, "CreationDate", (int)time(0));
16221613

1623-
IfcUtil::IfcBaseClass* quantity = nullptr;
1624-
aggregate_of_instance::ptr objects;
1614+
express::Base quantity;
1615+
std::vector<express::Base> objects;
16251616
boost::shared_ptr<IfcGeom::Representation::BRep> previous_geometry_pointer;
16261617

16271618
for (;; ++num_created) {
@@ -1636,7 +1627,7 @@ void fix_quantities(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool std
16361627

16371628
if (geom_object && geom_object->geometry_pointer() == previous_geometry_pointer) {
16381629
// @todo
1639-
objects->push(const_cast<IfcUtil::IfcBaseEntity*>(geom_object->product()));
1630+
objects.push_back(geom_object->product());
16401631
} else {
16411632
if (quantity) {
16421633
auto rel = latebound_access::create(f, "IfcRelDefinesByProperties");
@@ -1649,56 +1640,55 @@ void fix_quantities(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool std
16491640
break;
16501641
}
16511642

1652-
aggregate_of_instance::ptr quantities(new aggregate_of_instance);
1643+
std::vector<express::Base> quantities;
16531644

16541645
double a, b, c;
16551646
if (geom_object->geometry().calculate_surface_area(a)) {
16561647
auto quantity_area = latebound_access::create(f, "IfcQuantityArea");
16571648
latebound_access::set(quantity_area, "Name", std::string("Total Surface Area"));
16581649
latebound_access::set(quantity_area, "AreaValue", a);
1659-
quantities->push(quantity_area);
1650+
quantities.push_back(quantity_area);
16601651
}
16611652

16621653
if (geom_object->geometry().calculate_volume(a)) {
16631654
auto quantity_volume = latebound_access::create(f, "IfcQuantityVolume");
16641655
latebound_access::set(quantity_volume, "Name", std::string("Volume"));
16651656
latebound_access::set(quantity_volume, "VolumeValue", a);
1666-
quantities->push(quantity_volume);
1657+
quantities.push_back(quantity_volume);
16671658
}
16681659

16691660
if (geom_object->calculate_projected_surface_area(a, b, c)) {
16701661
auto quantity_area = latebound_access::create(f, "IfcQuantityArea");
16711662
latebound_access::set(quantity_area, "Name", std::string("Footprint Area"));
16721663
latebound_access::set(quantity_area, "AreaValue", c);
1673-
quantities->push(quantity_area);
1664+
quantities.push_back(quantity_area);
16741665
}
16751666

16761667
auto quantity_complex = latebound_access::create(f, "IfcPhysicalComplexQuantity");
16771668
latebound_access::set(quantity_complex, "Name", std::string("Shape Validation Properties"));
1678-
quantities->push(quantity_complex);
1669+
quantities.push_back(quantity_complex);
16791670

1680-
aggregate_of_instance::ptr quantities_2(new aggregate_of_instance);
1671+
std::vector<express::Base> quantities_2;
16811672

16821673
for (auto& part : geom_object->geometry()) {
16831674
auto quantity_count = latebound_access::create(f, "IfcQuantityCount");
16841675
latebound_access::set(quantity_count, "Name", std::string("Surface Genus"));
16851676
latebound_access::set(quantity_count, "Description", '#' + boost::lexical_cast<std::string>(part.ItemId()));
16861677
latebound_access::set(quantity_count, "CountValue", part.Shape()->surface_genus());
16871678

1688-
quantities_2->push(quantity_count);
1679+
quantities_2.push_back(quantity_count);
16891680
}
16901681

16911682
latebound_access::set(quantity_complex, "HasQuantities", quantities_2);
16921683

1693-
if (quantities->size()) {
1684+
if (!quantities.empty()) {
16941685
quantity = latebound_access::create(f, "IfcElementQuantity");
16951686
latebound_access::set(quantity, "OwnerHistory", ownerhist);
16961687
latebound_access::set(quantity, "Quantities", quantities);
16971688
}
16981689

1699-
objects.reset(new aggregate_of_instance);
17001690
// @todo
1701-
objects->push(const_cast<IfcUtil::IfcBaseEntity*>(geom_object->product()));
1691+
objects.push_back(geom_object->product());
17021692
}
17031693

17041694
previous_geometry_pointer = geom_object->geometry_pointer();

src/ifcgeom/AbstractKernel.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ bool ifcopenshell::geometry::kernels::AbstractKernel::convert(const taxonomy::pt
2020
auto it = cache_.find(item);
2121
if (it != cache_.end()) {
2222
results = it->second;
23-
Logger::Notice("Cache hit #" + std::to_string(item->instance->as<IfcUtil::IfcBaseEntity>()->id()) +
24-
" -> #" + std::to_string(it->first->instance->as<IfcUtil::IfcBaseEntity>()->id()));
23+
Logger::Notice("Cache hit #" + std::to_string(item->instance.id()) +
24+
" -> #" + std::to_string(it->first->instance.id()));
2525
return true;
2626
}
2727
}

src/ifcgeom/AbstractKernel.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,8 @@ namespace ifcopenshell {
121121
*/
122122

123123
virtual bool apply_layerset(IfcGeom::ConversionResults&, const ifcopenshell::geometry::layerset_information&) { throw not_implemented_error(); }
124-
virtual bool apply_folded_layerset(IfcGeom::ConversionResults&, const ifcopenshell::geometry::layerset_information&, const std::map<IfcUtil::IfcBaseEntity*, ifcopenshell::geometry::layerset_information>&) { throw not_implemented_error(); }
125-
virtual bool convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector<std::pair<taxonomy::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
124+
virtual bool apply_folded_layerset(IfcGeom::ConversionResults&, const ifcopenshell::geometry::layerset_information&, const std::map<express::Base, ifcopenshell::geometry::layerset_information>&) { throw not_implemented_error(); }
125+
virtual bool convert_openings(const express::Base& entity, const std::vector<std::pair<taxonomy::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
126126
const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes) = 0;
127127
virtual bool unify_shapes(const IfcGeom::ConversionResults&, IfcGeom::ConversionResults&) { throw not_implemented_error(); }
128128

src/ifcgeom/ConversionSettings.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,15 @@
55
#include <limits>
66
#include <string>
77
#include <iostream>
8-
#include <string>
98
#include <map>
109
#include <tuple>
1110
#include <type_traits>
11+
#include <optional>
12+
#include <variant>
1213

1314
#include <boost/program_options.hpp>
1415
#include <boost/optional.hpp>
15-
#include <boost/variant.hpp>
1616
#include <boost/algorithm/string.hpp>
17-
#include <boost/optional/optional_io.hpp>
1817

1918
#include "ifc_geom_api.h"
2019

@@ -48,7 +47,8 @@ namespace ifcopenshell {
4847
// of vector settings we need to strip away the optional and detect argument presence
4948
// with !vector::empty()
5049
// tfk: we no longer do this because negative values can not be passed like this as boost confuses them with options
51-
// std::conditional_t<std::is_same_v<T, std::vector<double>>, T, boost::optional<T>> value;
50+
// std::conditional_t<std::is_same_v<T, std::vector<double>>, T, std::optional<T>> value;
51+
// tfk: note that we use boost::optional to avoid a lack of deserialization support with std::optional and boost program options
5252
boost::optional<T> value;
5353

5454
SettingBase() {}
@@ -80,7 +80,7 @@ namespace ifcopenshell {
8080
return value;
8181
} else {
8282
if (value) {
83-
return value.get();
83+
return value.value();
8484
}
8585
if constexpr (HasDefault<Derived>()) {
8686
return Derived::defaultvalue;
@@ -539,7 +539,7 @@ namespace ifcopenshell {
539539
template <typename settings_t>
540540
class SettingsContainer {
541541
public:
542-
typedef boost::variant<bool, int, double, std::string, std::set<int>, std::set<std::string>, std::vector<double>, IteratorOutputOptions, FunctionStepMethod, OutputDimensionalityTypes, TriangulationMethod> value_variant_t;
542+
typedef std::variant<bool, int, double, std::string, std::set<int>, std::set<std::string>, std::vector<double>, IteratorOutputOptions, FunctionStepMethod, OutputDimensionalityTypes, TriangulationMethod> value_variant_t;
543543
private:
544544
settings_t settings;
545545

@@ -579,15 +579,15 @@ namespace ifcopenshell {
579579
void set_option_(const std::string& name, const value_variant_t& val) {
580580
if (std::tuple_element_t<Index, settings_t>::name == name) {
581581
if constexpr (std::is_enum_v<typename std::tuple_element_t<Index, settings_t>::base_type>) {
582-
if (auto* val_ptr = boost::get<int>(&val)) {
582+
if (auto* val_ptr = std::get_if<int>(&val)) {
583583
auto val_as_enum = (typename std::tuple_element_t<Index, settings_t>::base_type) *val_ptr;
584584
std::get<Index>(settings).value = val_as_enum;
585585
return;
586586
}
587587
}
588588
try {
589-
std::get<Index>(settings).value = boost::get<typename std::tuple_element_t<Index, settings_t>::base_type>(val);
590-
} catch (const boost::bad_get&) {
589+
std::get<Index>(settings).value = std::get<typename std::tuple_element_t<Index, settings_t>::base_type>(val);
590+
} catch (const std::bad_variant_access&) {
591591
std::string ty = impl::readable_name<typename std::tuple_element_t<Index, settings_t>::base_type>::name;
592592
throw std::runtime_error("Expected a value of type <" + ty + "> for setting '" + name + "'");
593593
}

0 commit comments

Comments
 (0)