Work on LOD example

This commit is contained in:
Thomas Krijnen
2017-12-06 17:51:18 +01:00
parent 89e97e5d7c
commit d8d82eb6ec
3 changed files with 146 additions and 19 deletions
+48 -10
View File
@@ -94,20 +94,21 @@ void find_geometric_types(IfcParse::IfcFile& f, const std::string& tfn) {
return a->data().id() < b->data().id();
});
IfcSchema::IfcStyledItem::list::ptr styles = f.entitiesByType<IfcSchema::IfcStyledItem>();
std::set<IfcSchema::Type::Enum> geometric_types{ IfcSchema::Type::IfcStyledItem };
std::set<IfcSchema::Type::Enum> geometric_types{ IfcSchema::Type::IfcStyledItem, IfcSchema::Type::IfcMaterialDefinitionRepresentation, IfcSchema::Type::IfcStyledRepresentation };
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);
});
for (auto ty : geometric_types) {
auto insts = f.entitiesByType(ty);
std::for_each(insts->begin(), insts->end(), [&geometric_instances](IfcUtil::IfcBaseClass* inst) {
geometric_instances.insert(inst);
});
}
int N, n;
auto vist_geometric = [&f, &geometric_types, &geometric_instances, N, &n](IfcUtil::IfcBaseEntity* def) {
auto vist_geometric = [&f, &geometric_types, &geometric_instances, &N, &n](IfcUtil::IfcBaseEntity* 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) {
@@ -116,7 +117,7 @@ void find_geometric_types(IfcParse::IfcFile& f, const std::string& tfn) {
}
});
if (n++ % 1000 == 0) {
std::cerr << "\r" << n * 100 / N << std::flush;
std::cerr << "\r" << (n * 100 / N) << std::flush;
}
};
@@ -136,6 +137,16 @@ void find_geometric_types(IfcParse::IfcFile& f, const std::string& tfn) {
fn = [&f, &geometric_instances, &other_types, &fn](IfcUtil::IfcBaseClass* root, IfcUtil::IfcBaseClass* inst) {
if (geometric_instances.find(inst) == geometric_instances.end()) {
auto ty = inst->declaration().type();
if (ty == IfcSchema::Type::IfcExtrudedAreaSolid) {
std::cerr << inst->data().toString() << " reachded by " << root->data().toString() << std::endl;
}
// Not referenced. Revit generates unused IfcExtrudedAreaSolids some times.
auto invs = f.getInverse(inst->data().id(), IfcSchema::Type::UNDEFINED, -1);
if (root == inst && invs->size() == 0) {
return;
}
other_types.insert(ty);
auto refs = f.traverse(inst, 1);
std::for_each(refs->begin() + 1, refs->end(), [&fn, root](IfcUtil::IfcBaseClass* inst) {
@@ -170,6 +181,8 @@ void find_geometric_types(IfcParse::IfcFile& f, const std::string& tfn) {
const size_t name = ty;
str.write((char*)&name, sizeof(size_t));
}
std::cin.get();
}
int main(int argc, char** argv) {
@@ -214,10 +227,21 @@ int main(int argc, char** argv) {
}
std::set<IfcSchema::Type::Enum> property_types {
IfcSchema::Type::IfcRelDefines, IfcSchema::Type::IfcPropertySetDefinition, IfcSchema::Type::IfcTypeObject
IfcSchema::Type::IfcRelDefines,
IfcSchema::Type::IfcPropertySetDefinition,
IfcSchema::Type::IfcTypeObject,
IfcSchema::Type::IfcProperty,
IfcSchema::Type::IfcPhysicalQuantity,
IfcSchema::Type::IfcRelAssociatesClassification,
IfcSchema::Type::IfcRelAssociatesMaterial,
IfcSchema::Type::IfcMaterialList,
IfcSchema::Type::IfcMaterialLayerSetUsage,
IfcSchema::Type::IfcMaterialLayerSet,
IfcSchema::Type::IfcMaterialLayer,
IfcSchema::Type::IfcMaterial
};
std::vector<IfcUtil::IfcBaseClass*> new_defs, old_defs, old_prop_defs, old_geom_defs, all_old_defs, all_defs;
std::vector<IfcUtil::IfcBaseClass*> new_defs, old_defs, old_prop_defs, old_geom_defs, old_box_defs, all_old_defs, all_defs;
std::for_each(only_geometric.begin(), only_geometric.end(), [&f, &old_geom_defs](IfcSchema::Type::Enum t) {
auto insts = f.entitiesByType(t);
@@ -312,6 +336,10 @@ int main(int argc, char** argv) {
all_old_defs.insert(all_old_defs.end(), old_geom_defs.begin(), old_geom_defs.end());
all_defs.insert(all_defs.end(), all_old_defs.begin(), all_old_defs.end());
all_defs.insert(all_defs.end(), new_defs.begin(), new_defs.end());
old_box_defs.insert(old_box_defs.end(), old_defs.begin(), old_defs.end());
old_box_defs.insert(old_box_defs.end(), new_defs.begin(), new_defs.end());
auto contexts = f.entitiesByType<IfcSchema::IfcRepresentationContext>();
old_box_defs.insert(old_box_defs.end(), contexts->begin(), contexts->end());
{
int num_insts1 = std::distance(all_old_defs.begin(), all_old_defs.end());
@@ -329,6 +357,7 @@ int main(int argc, char** argv) {
IfcParse::Hdf5Settings settings;
settings.profile() = IfcParse::Hdf5Settings::padded;
settings.compress() = true;
settings.chunk_size() = 256;
H5::H5File hdf(argv[1] + std::string(".hdf"), H5F_ACC_TRUNC);
H5::H5File geom_hdf(argv[1] + std::string("-geometry.hdf"), H5F_ACC_TRUNC);
@@ -367,5 +396,14 @@ int main(int argc, char** argv) {
IfcParse::instance_enumerator enumerator(&f.header(), old_prop_defs.begin(), old_prop_defs.end());
ifc_hdf5.write_population(prop_population, enumerator, locator);
}
{
// locator is setup with all_old_defs, need to switch to new_defs + old_defs for the cartesian points
// NB: also geom rep context
locator->next(box_population, old_box_defs.begin(), old_box_defs.end());
IfcParse::instance_enumerator enumerator(&f.header(), new_defs.begin(), new_defs.end());
ifc_hdf5.write_population(box_population, enumerator, locator);
}
}
}
@@ -202,6 +202,30 @@ public:
ptr = static_cast<uint8_t*>(ptr) + sizeof(hdset_reg_ref_t);
}
template <typename ForwardIt>
void next(H5::Group& group, ForwardIt insts_begin, ForwardIt insts_end) {
subsequent_group_ = &group;
subsequent_population_.first = initial_population_.first;
subsequent_population_.second.clear();
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();
});
subsequent_population_.second.emplace_back(by_type);
});
}
void next(const std::string& name, H5::Group& group, IfcParse::IfcFile* f) {
subsequent_group_ = &group;
root_ = name;
+74 -9
View File
@@ -1844,16 +1844,30 @@ private:
H5::H5File& file_;
H5::Group& population_group_;
std::vector<std::string> dataset_names_;
std::vector<std::string> dataset_paths_;
std::vector<bool> dataset_paths_warnings_emitted;
std::map<std::string, int>* name_mapping_;
std::map<std::pair<hsize_t, hsize_t>, size_t> cache_;
public:
instance_resolver(H5::H5File& file, H5::Group& population_group, std::map<std::string, int>* name_mapping = nullptr)
instance_resolver(H5::H5File& file, H5::Group& population_group, std::map<std::string, int>* name_mapping = nullptr, std::map<std::string, std::string>* path_mapping = nullptr)
: file_(file)
, population_group_(population_group)
, name_mapping_(name_mapping)
{
dataset_names_ = read_attribute(population_group_, "iso_10303_26_data_set_names");
if (name_mapping != nullptr) {
for (const auto& s : dataset_names_) {
auto it = path_mapping->find(s);
if (it == path_mapping->end()) {
dataset_paths_.push_back("");
} else {
dataset_paths_.push_back(it->second);
}
}
}
dataset_paths_warnings_emitted.resize(dataset_names_.size());
}
size_t instance_name(const std::string& path, int row) {
@@ -1877,9 +1891,29 @@ public:
pair[i] = read<int>((uint8_t*)data + offset, &mt);
}
const std::string& nm = dataset_names_[pair[0]];
auto ppair = std::make_pair(pair[0], pair[1]);
H5::DataSet dataset = file_.openDataSet("population/" + nm + "_instances");
auto cache_it = cache_.find(ppair);
if (cache_it != cache_.end()) {
return cache_it->second;
}
std::string path;
if (dataset_paths_.empty()) {
const std::string& nm = dataset_names_[pair[0]];
path = "population/" + nm + "_instances";
} else {
path = dataset_paths_[pair[0]];
if (path.empty()) {
if (!dataset_paths_warnings_emitted[pair[0]]) {
std::cerr << "No dataset loaded for '" << dataset_names_[pair[0]] << "'" << std::endl;
}
dataset_paths_warnings_emitted[pair[0]] = true;
return 0;
}
}
H5::DataSet dataset = file_.openDataSet(path);
H5::CompType datatype = dataset.getCompType();
H5::DataSpace dataspace = dataset.getSpace();
if (dataspace.getSimpleExtentNdims() != 1) {
@@ -1906,6 +1940,8 @@ public:
delete[] buffer;
cache_.insert(std::make_pair(ppair, inst_name));
return inst_name;
} else if (dt->getClass() == H5T_REFERENCE) {
@@ -2155,6 +2191,7 @@ struct hdf5_output_info {
std::ostream& output;
std::map<std::string, int>* name_mapping;
std::map<std::string, std::string>* path_mapping;
};
herr_t iterate(hid_t id, const char *path, const H5O_info_t *object_info, void *op_data) {
@@ -2163,10 +2200,12 @@ herr_t iterate(hid_t id, const char *path, const H5O_info_t *object_info, void *
if (object_info->type == H5O_TYPE_DATASET) {
H5::Group population_group(id);
instance_resolver resolver(f, population_group, ((hdf5_output_info*)op_data)->name_mapping);
instance_resolver resolver(f, population_group, ((hdf5_output_info*)op_data)->name_mapping, ((hdf5_output_info*)op_data)->path_mapping);
std::string name = path;
std::cerr << name << std::endl;
H5::DataSet dataset = population_group.openDataSet(name);
H5::DataType datatype = dataset.getDataType();
H5::DataSpace dataspace = dataset.getSpace();
@@ -2218,13 +2257,15 @@ private:
H5::H5File& file_;
bool finished_schema_;
std::map<std::string, int>* offset_mapping_;
std::map<std::string, std::string>* path_mapping_;
int last_offset_;
public:
file_structure(H5::H5File& file, std::map<std::string, int>* offset_mapping = nullptr)
file_structure(H5::H5File& file, std::map<std::string, int>* offset_mapping = nullptr, std::map<std::string, std::string>* path_mapping = nullptr)
: file_(file)
, finished_schema_(false)
, offset_mapping_(offset_mapping)
, path_mapping_(path_mapping)
, last_offset_(1)
{}
@@ -2252,6 +2293,27 @@ public:
offset_mapping_->insert({ds.getObjName(), last_offset_});
last_offset_ += dims;
}
if (path_mapping_) {
/*
std::string datatype = ds.getDataType().getObjName();
auto it = datatype.rfind('/');
if (it != std::string::npos) {
datatype = datatype.substr(it + 1);
}
*/
std::string name = ds.getObjName();
std::string path = name;
auto it = path.rfind('/');
if (it != std::string::npos) {
path = path.substr(it + 1);
}
it = path.find('_');
if (it != std::string::npos) {
path = path.substr(0, it);
}
path_mapping_->insert({ path, name });
}
}
void finished_schema() { finished_schema_ = true; }
@@ -2306,6 +2368,11 @@ void IfcParse::IfcHdf5File::convert_to_spf(const std::string& name, std::ostream
H5::H5File f(name, H5F_ACC_RDONLY);
std::vector<H5::H5File*> children;
std::map<std::string, int> offset_mapping;
std::map<std::string, std::string> path_mapping;
file_structure fs(f, &offset_mapping, &path_mapping);
if (mount_points) {
std::transform(mount_points->begin(), mount_points->end(), std::back_inserter(children), [&f](const std::string& directive) {
@@ -2328,15 +2395,13 @@ void IfcParse::IfcHdf5File::convert_to_spf(const std::string& name, std::ostream
});
}
std::map<std::string, int> offset_mapping;
file_structure fs(f, &offset_mapping);
H5Ovisit(f.getId(), H5_INDEX_NAME, H5_ITER_NATIVE, find_datasets, &fs);
H5Ovisit(f.getId(), H5_INDEX_NAME, H5_ITER_NATIVE, find_groups, &fs);
fs.finished_schema();
H5Ovisit(f.getId(), H5_INDEX_NAME, H5_ITER_NATIVE, find_groups, &fs);
hdf5_output_info info{ f, output, &offset_mapping };
hdf5_output_info info{ f, output, &offset_mapping, &path_mapping };
for (auto it = fs.begin(); it != fs.end(); ++it) {
auto& group = it->first;
auto& schema_id = it->second->first;