Work on LOD use case

This commit is contained in:
Thomas Krijnen
2017-11-25 09:47:42 +01:00
parent 03a82fe301
commit 226a02adfc
3 changed files with 179 additions and 11 deletions
+2 -2
View File
@@ -18,7 +18,7 @@
################################################################################
ADD_EXECUTABLE(hdf5_federate federate.cpp)
TARGET_LINK_LIBRARIES(hdf5_federate IfcParse)
TARGET_LINK_LIBRARIES(hdf5_federate IfcParse ${ICU_LIBRARIES} ${Boost_LIBRARIES})
ADD_EXECUTABLE(hdf5_lod lod.cpp)
TARGET_LINK_LIBRARIES(hdf5_lod IfcParse IfcGeom)
TARGET_LINK_LIBRARIES(hdf5_lod IfcParse IfcGeom ${OPENCASCADE_LIBRARIES} ${Boost_LIBRARIES} ${ICU_LIBRARIES})
+148 -3
View File
@@ -19,21 +19,113 @@
#include "../../../src/ifcparse/IfcHdf5File.h"
#include "../../../src/ifcgeom/IfcGeom.h"
#include "../../../src/ifcparse/IfcWritableEntity.h"
#include <Bnd_Box.hxx>
#include <BRepBndLib.hxx>
#include <algorithm>
#include "multifile_instance_locator.h"
int main(int, char** argv) {
IfcParse::IfcFile f;
f.Init(argv[1]);
std::vector<IfcSchema::IfcProductDefinitionShape*> new_defs;
IfcSchema::IfcProductDefinitionShape::list::ptr defs = f.entitiesByType<IfcSchema::IfcProductDefinitionShape>();
IfcSchema::IfcProductDefinitionShape::list::ptr defs_ = f.entitiesByType<IfcSchema::IfcProductDefinitionShape>();
std::vector<IfcSchema::IfcProductDefinitionShape*> defs(defs_->begin(), defs_->end());
// Make sure to sort by id to have new definitions lining up in the same order
std::sort(defs.begin(), defs.end(), [](IfcSchema::IfcProductDefinitionShape* a, IfcSchema::IfcProductDefinitionShape* b) {
return a->data().id() < b->data().id();
});
IfcSchema::IfcStyledItem::list::ptr styles = f.entitiesByType<IfcSchema::IfcStyledItem>();
IfcGeom::Kernel kernel;
kernel.initializeUnits(*f.entitiesByType<IfcSchema::IfcUnitAssignment>()->begin());
std::transform(defs->begin(), defs->end(), std::back_inserter(new_defs), [&kernel](IfcSchema::IfcProductDefinitionShape* def) {
std::set<IfcSchema::Type::Enum> geometric_types{ IfcSchema::Type::IfcStyledItem };
std::set<IfcSchema::Type::Enum> other_types;
std::set<IfcUtil::IfcBaseClass*> geometric_instances;
std::for_each(styles->begin(), styles->end(), [&geometric_instances](IfcSchema::IfcStyledItem* style) {
geometric_instances.insert(style);
});
int N = defs.size();
int n = 0;
std::for_each(defs.begin(), defs.end(), [&f, &geometric_types, &geometric_instances, N, &n](IfcSchema::IfcProductDefinitionShape* def) {
auto refs = f.traverse(def);
geometric_instances.insert(refs->begin(), refs->end());
std::for_each(refs->begin(), refs->end(), [&geometric_types](IfcUtil::IfcBaseClass* inst) {
geometric_types.insert(inst->declaration().type());
});
if (n++ % 1000 == 0) {
std::cerr << "\r" << n * 100 / N << std::flush;
}
});
std::function<void(IfcUtil::IfcBaseClass*, IfcUtil::IfcBaseClass*)> fn;
fn = [&f, &geometric_instances, &other_types, &fn](IfcUtil::IfcBaseClass* root, IfcUtil::IfcBaseClass* inst) {
if (geometric_instances.find(inst) == geometric_instances.end()) {
if (inst->declaration().type() == IfcSchema::Type::IfcCircle) {
std::cerr << "circle reached by " << root->data().toString() << std::endl;
}
other_types.insert(inst->declaration().type());
auto refs = f.traverse(inst, 1);
std::for_each(refs->begin() + 1, refs->end(), [&fn, root](IfcUtil::IfcBaseClass* inst) {
fn(root, inst);
});
}
};
N = std::distance(f.begin(), f.end());
n = 0;
std::for_each(f.begin(), f.end(), [&fn, N, &n](const auto& pair) {
fn(pair.second, pair.second);
if (n++ % 1000 == 0) {
std::cerr << "\r" << n * 100 / N << std::flush;
}
});
std::set<IfcSchema::Type::Enum> only_geometric;
std::set_difference(geometric_types.begin(), geometric_types.end(),
other_types.begin(), other_types.end(),
std::inserter(only_geometric, only_geometric.begin()));
for (auto ty : only_geometric) {
std::cerr << IfcSchema::Type::ToString(ty) << std::endl;
}
std::cin.get();
// IfcSchema::Type::IfcAxis2Placement3D,IfcSchema::Type::IfcCartesianPoint,IfcSchema::Type::IfcDirection,IfcSchema::Type::IfcGeometricRepresentationSubContext
std::vector<IfcUtil::IfcBaseClass*> new_defs, old_defs, old_geom_defs, all_old_defs;
std::for_each(only_geometric.begin(), only_geometric.end(), [&f, &old_geom_defs](IfcSchema::Type::Enum t) {
auto insts = f.entitiesByType(t);
std::for_each(insts->begin(), insts->end(), [t, &old_geom_defs](IfcUtil::IfcBaseClass* inst) {
if (inst->declaration().type() == t) {
old_geom_defs.push_back(inst);
}
});
});
std::for_each(f.begin(), f.end(), [&fn, &only_geometric, &old_defs](const auto& pair) {
IfcUtil::IfcBaseClass* inst = pair.second;
auto ty = inst->declaration().type();
if (only_geometric.find(ty) == only_geometric.end()) {
old_defs.push_back(inst);
}
});
auto id = f.FreshId();
std::for_each(defs.begin(), defs.end(), [&kernel, &id, &old_defs, &new_defs](IfcSchema::IfcProductDefinitionShape* def) {
Bnd_Box box;
auto reps = def->Representations();
IfcSchema::IfcRepresentationContext* context;
@@ -64,6 +156,59 @@ int main(int, char** argv) {
new_reps->push(rep);
IfcSchema::IfcProductDefinitionShape* new_def = new IfcSchema::IfcProductDefinitionShape(boost::none, boost::none, new_reps);
new_def->data().isWritable()->setId(id++);
// NB: Corner is added to existing definitions
old_defs.push_back(corner);
new_defs.push_back(bbox);
new_defs.push_back(rep);
new_defs.push_back(new_def);
return new_def;
});
H5::H5File hdf(argv[1] + std::string(".hdf"), H5F_ACC_TRUNC);
H5::Group population = hdf.createGroup("population");
H5::Group low = hdf.createGroup("low");
H5::Group hi = hdf.createGroup("hi");
auto iden = [](IfcUtil::IfcBaseClass* inst) { return inst; };
std::set<IfcSchema::Type::Enum> old_new_geom_types;
std::vector<std::vector<IfcUtil::IfcBaseClass*>*> all_vectors = std::vector<std::vector<IfcUtil::IfcBaseClass*>*>{ &new_defs, &old_defs, &old_geom_defs };
for (auto vec_ : all_vectors) {
auto& vec = *vec_;
for (auto& inst : vec) {
old_new_geom_types.insert(inst->declaration().type());
}
}
all_old_defs.insert(all_old_defs.end(), old_defs.begin(), old_defs.end());
all_old_defs.insert(all_old_defs.end(), old_geom_defs.begin(), old_geom_defs.end());
if (std::distance(all_old_defs.begin(), all_old_defs.end()) != std::distance(f.begin(), f.end())) {
std::cerr << "Missign instances";
abort();
}
multifile_instance_locator* locator = new multifile_instance_locator(
old_new_geom_types.begin(), old_new_geom_types.end(),
all_old_defs.begin(), all_old_defs.end());
IfcParse::Hdf5Settings settings;
// settings.profile() = IfcParse::Hdf5Settings::standard_referenced;
IfcParse::IfcHdf5File ifc_hdf5(hdf, get_schema(), settings);
ifc_hdf5.write_schema();
IfcParse::IfcSpfHeader header;
header.set_default();
{
IfcParse::instance_enumerator enumerator(&f.header(), old_defs.begin(), old_defs.end());
ifc_hdf5.write_population(population, enumerator, locator);
}
}
+29 -6
View File
@@ -27,16 +27,17 @@ public:
typedef std::vector<IfcUtil::IfcBaseClass*>::const_iterator full_const_iterator;
private:
H5::H5File& root_file_;
H5::H5File* root_file_;
mapping_t mapping_;
std::set<IfcUtil::IfcBaseClass*> initial_population_set_;
std::set<IfcSchema::Type::Enum> initial_types_included_set_;
population_t initial_population_;
population_t subsequent_population_;
std::vector<IfcUtil::IfcBaseClass*> subsequent_minus_initial_;
H5::Group& initial_group_;
H5::Group* initial_group_;
H5::Group* subsequent_group_;
H5::H5File* subsequent_file_;
std::string root_;
@@ -45,9 +46,9 @@ public:
template <typename ForwardIterator>
multifile_instance_locator(H5::H5File& root_file, H5::Group& group, mapping_t mapping, ForwardIterator b, ForwardIterator e)
: root_file_(root_file)
: root_file_(&root_file)
, mapping_(mapping)
, initial_group_(group)
, initial_group_(&group)
, subsequent_group_(nullptr)
{
initial_population_set_.insert(b, e);
@@ -80,6 +81,28 @@ public:
});
}
template <typename ForwardIteratorTypes, typename ForwardIteratorInsts>
multifile_instance_locator(ForwardIteratorTypes types_all_begin, ForwardIteratorTypes types_all_end, ForwardIteratorInsts insts_begin, ForwardIteratorInsts insts_end) {
initial_population_.first.assign(types_all_begin, types_all_end);
std::sort(initial_population_.first.begin(), initial_population_.first.end());
std::for_each(this->begin(), this->end(), [this, &insts_begin, &insts_end](IfcSchema::Type::Enum t) {
std::vector<IfcUtil::IfcBaseEntity*> by_type;
std::for_each(insts_begin, insts_end, [t, &by_type](IfcUtil::IfcBaseClass* inst) {
if (inst->declaration().type() == t && inst->declaration().as_entity()) {
by_type.push_back((IfcUtil::IfcBaseEntity*) inst);
}
});
std::sort(by_type.begin(), by_type.end(), [](IfcUtil::IfcBaseEntity* i1, IfcUtil::IfcBaseEntity* i2) {
return i1->data().id() < i2->data().id();
});
initial_population_.second.emplace_back(by_type);
});
}
const_iterator begin() const {
if (subsequent_group_) {
return subsequent_population_.first.begin();
@@ -126,7 +149,7 @@ public:
if (initial_population_set_.find(v) != initial_population_set_.end()) {
pop = &initial_population_;
group = &initial_group_;
group = initial_group_;
current_root = boost::none;
} else {
pop = &subsequent_population_;
@@ -148,7 +171,7 @@ public:
std::string full_path = group->getObjName() + "/" + path + "_instances";
root_file_.reference(ptr, full_path, space);
root_file_->reference(ptr, full_path, space);
ptr = static_cast<uint8_t*>(ptr) + sizeof(hdset_reg_ref_t);
}