Work on LOD use case

This commit is contained in:
Thomas Krijnen
2017-12-04 17:19:31 +01:00
parent 6ca5c90517
commit 20eb913b65
+146 -79
View File
@@ -28,9 +28,52 @@
#include "multifile_instance_locator.h" #include "multifile_instance_locator.h"
int main(int, char** argv) { void generate_bounding_boxes(IfcParse::IfcFile& f, const std::string& fn) {
IfcParse::IfcFile f; IfcGeom::Kernel kernel;
f.Init(argv[1]); kernel.initializeUnits(*f.entitiesByType<IfcSchema::IfcUnitAssignment>()->begin());
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();
});
std::ofstream str(fn.c_str(), std::ios_base::binary);
std::for_each(defs.begin(), defs.end(), [&kernel, &str](IfcSchema::IfcProductDefinitionShape* def) {
Bnd_Box box;
auto reps = def->Representations();
IfcSchema::IfcRepresentationContext* context;
std::for_each(reps->begin(), reps->end(), [&kernel, &box, &context](auto rep) {
IfcGeom::IfcRepresentationShapeItems items;
if (rep->RepresentationIdentifier() == "Body") {
// kernel.convert(rep, items);
context = rep->ContextOfItems();
}
for (auto& i : items) {
BRepBndLib::AddClose(i.Shape(), box);
}
});
box.Add(gp_Pnt(0, 0, 0));
const size_t name = def->data().id();
double xyz[6];
box.Get(xyz[0], xyz[1], xyz[2], xyz[3], xyz[4], xyz[5]);
str.write((char*)&name, sizeof(size_t));
str.write((char*)xyz, sizeof(double) * 6);
});
}
void find_geometric_types(IfcParse::IfcFile& f, const std::string& tfn) {
std::ofstream str(tfn.c_str(), std::ios_base::binary);
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()); std::vector<IfcSchema::IfcProductDefinitionShape*> defs(defs_->begin(), defs_->end());
@@ -41,11 +84,6 @@ int main(int, char** argv) {
IfcSchema::IfcStyledItem::list::ptr styles = f.entitiesByType<IfcSchema::IfcStyledItem>(); IfcSchema::IfcStyledItem::list::ptr styles = f.entitiesByType<IfcSchema::IfcStyledItem>();
IfcGeom::Kernel kernel;
kernel.initializeUnits(*f.entitiesByType<IfcSchema::IfcUnitAssignment>()->begin());
/*
std::set<IfcSchema::Type::Enum> geometric_types{ IfcSchema::Type::IfcStyledItem }; std::set<IfcSchema::Type::Enum> geometric_types{ IfcSchema::Type::IfcStyledItem };
std::set<IfcSchema::Type::Enum> other_types; std::set<IfcSchema::Type::Enum> other_types;
@@ -55,30 +93,43 @@ int main(int, char** argv) {
geometric_instances.insert(style); geometric_instances.insert(style);
}); });
int N = defs.size(); int N, n;
int n = 0;
std::for_each(defs.begin(), defs.end(), [&f, &geometric_types, &geometric_instances, N, &n](IfcSchema::IfcProductDefinitionShape* def) { auto vist_geometric = [&f, &geometric_types, &geometric_instances, N, &n](IfcUtil::IfcBaseEntity* def) {
auto refs = f.traverse(def); auto refs = f.traverse(def);
geometric_instances.insert(refs->begin(), refs->end()); geometric_instances.insert(refs->begin(), refs->end());
std::for_each(refs->begin(), refs->end(), [&geometric_types](IfcUtil::IfcBaseClass* inst) { std::for_each(refs->begin(), refs->end(), [&geometric_types](IfcUtil::IfcBaseClass* inst) {
geometric_types.insert(inst->declaration().type()); if (inst->declaration().as_entity()) {
geometric_types.insert(inst->declaration().type());
}
}); });
if (n++ % 1000 == 0) { if (n++ % 1000 == 0) {
std::cerr << "\r" << n * 100 / N << std::flush; std::cerr << "\r" << n * 100 / N << std::flush;
} }
}); };
n = 0;
N = defs.size();
std::for_each(defs.begin(), defs.end(), vist_geometric);
auto connection_geom = f.entitiesByType<IfcSchema::IfcConnectionGeometry>();
n = 0;
N = connection_geom->size();
std::for_each(connection_geom->begin(), connection_geom->end(), vist_geometric);
std::function<void(IfcUtil::IfcBaseClass*, IfcUtil::IfcBaseClass*)> fn; std::function<void(IfcUtil::IfcBaseClass*, IfcUtil::IfcBaseClass*)> fn;
fn = [&f, &geometric_instances, &other_types, &fn](IfcUtil::IfcBaseClass* root, IfcUtil::IfcBaseClass* inst) { fn = [&f, &geometric_instances, &other_types, &fn, &to_watch](IfcUtil::IfcBaseClass* root, IfcUtil::IfcBaseClass* inst) {
if (geometric_instances.find(inst) == geometric_instances.end()) { if (geometric_instances.find(inst) == geometric_instances.end()) {
if (inst->declaration().type() == IfcSchema::Type::IfcCircle) { auto ty = inst->declaration().type();
std::cerr << "circle reached by " << root->data().toString() << std::endl; other_types.insert(ty);
}
other_types.insert(inst->declaration().type());
auto refs = f.traverse(inst, 1); auto refs = f.traverse(inst, 1);
std::for_each(refs->begin() + 1, refs->end(), [&fn, root](IfcUtil::IfcBaseClass* inst) { std::for_each(refs->begin() + 1, refs->end(), [&fn, root](IfcUtil::IfcBaseClass* inst) {
fn(root, inst); if (inst->declaration().as_entity()) {
fn(root, inst);
}
}); });
} }
}; };
@@ -98,34 +149,57 @@ int main(int, char** argv) {
other_types.begin(), other_types.end(), other_types.begin(), other_types.end(),
std::inserter(only_geometric, only_geometric.begin())); std::inserter(only_geometric, only_geometric.begin()));
only_geometric.erase(IfcSchema::Type::IfcGeometricRepresentationContext);
std::cerr << "\nOnly geometric:" << std::endl; std::cerr << "\nOnly geometric:" << std::endl;
for (auto ty : only_geometric) { for (auto ty : only_geometric) {
std::cerr << IfcSchema::Type::ToString(ty) << std::endl; std::cerr << IfcSchema::Type::ToString(ty) << std::endl;
const size_t name = ty;
str.write((char*)&name, sizeof(size_t));
}
}
int main(int argc, char** argv) {
const std::string cache_fn = argv[1] + std::string(".boxes.bin");
const std::string types_fn = argv[1] + std::string(".types.bin");
if (argc == 2 && !ifstream(cache_fn).good()) {
std::string command = std::string("\"\"") + argv[0] + "\" \"" + argv[1] + "\" -b\"";
if (system(command.c_str()) != 0) {
return 1;
}
} }
*/ if (argc == 2 && !ifstream(types_fn).good()) {
std::string command = std::string("\"\"") + argv[0] + "\" \"" + argv[1] + "\" -t\"";
if (system(command.c_str()) != 0) {
return 1;
}
}
std::set<IfcSchema::Type::Enum> only_geometric{ IfcParse::IfcFile f;
IfcSchema::Type::IfcAxis2Placement2D , f.Init(argv[1]);
IfcSchema::Type::IfcCartesianTransformationOperator3D,
IfcSchema::Type::IfcCircleProfileDef , if (argc == 3 && std::string(argv[2]) == "-b") {
IfcSchema::Type::IfcClosedShell , generate_bounding_boxes(f, cache_fn);
IfcSchema::Type::IfcConnectedFaceSet , return 0;
IfcSchema::Type::IfcExtrudedAreaSolid , }
IfcSchema::Type::IfcFace ,
IfcSchema::Type::IfcFaceBasedSurfaceModel , if (argc == 3 && std::string(argv[2]) == "-t") {
IfcSchema::Type::IfcFaceBound , find_geometric_types(f, types_fn);
IfcSchema::Type::IfcFaceOuterBound , return 0;
IfcSchema::Type::IfcFacetedBrep , }
//IfcSchema::Type::IfcGeometricRepresentationContext ,
IfcSchema::Type::IfcMappedItem , std::set<IfcSchema::Type::Enum> only_geometric;
IfcSchema::Type::IfcPolyLoop , {
IfcSchema::Type::IfcProductDefinitionShape , std::ifstream str(types_fn.c_str(), std::ios_base::binary);
IfcSchema::Type::IfcRepresentationMap , while (!str.eof()) {
IfcSchema::Type::IfcShapeRepresentation , size_t name;
IfcSchema::Type::IfcStyledItem str.read((char*)&name, sizeof(size_t));
}; only_geometric.insert((IfcSchema::Type::Enum) name);
}
}
std::vector<IfcUtil::IfcBaseClass*> new_defs, old_defs, old_geom_defs, all_old_defs, all_defs; std::vector<IfcUtil::IfcBaseClass*> new_defs, old_defs, old_geom_defs, all_old_defs, all_defs;
@@ -146,54 +220,47 @@ int main(int, char** argv) {
} }
}); });
auto id = f.FreshId(); IfcSchema::IfcRepresentationContext* context = 0;
auto reps = (*f.entitiesByType<IfcSchema::IfcProductDefinitionShape>()->begin())->Representations();
std::for_each(reps->begin(), reps->end(), [&context](auto rep) {
IfcGeom::IfcRepresentationShapeItems items;
if (rep->RepresentationIdentifier() == "Body") {
context = rep->ContextOfItems();
}
});
auto id = f.FreshId();
int num_points_added = 0; int num_points_added = 0;
std::for_each(defs.begin(), defs.end(), [&kernel, &id, &old_defs, &new_defs, &num_points_added](IfcSchema::IfcProductDefinitionShape* def) { {
Bnd_Box box; std::ifstream str(cache_fn.c_str(), std::ios_base::binary);
auto reps = def->Representations(); while (!str.eof()) {
IfcSchema::IfcRepresentationContext* context; size_t name;
double xyz[6];
std::for_each(reps->begin(), reps->end(), [&kernel, &box, &context](auto rep) { str.read((char*)&name, sizeof(size_t));
IfcGeom::IfcRepresentationShapeItems items; str.read((char*)xyz, sizeof(size_t));
if (rep->RepresentationIdentifier() == "Body") { IfcSchema::IfcCartesianPoint* corner = new IfcSchema::IfcCartesianPoint(std::vector<double>{xyz[0], xyz[1], xyz[2]});;
// kernel.convert(rep, items); IfcSchema::IfcBoundingBox* bbox = new IfcSchema::IfcBoundingBox(corner, xyz[3] - xyz[0], xyz[4] - xyz[1], xyz[5] - xyz[2]);
context = rep->ContextOfItems(); IfcSchema::IfcRepresentationItem::list::ptr items(new IfcSchema::IfcRepresentationItem::list);
} items->push(bbox);
for (auto& i : items) { IfcSchema::IfcShapeRepresentation* rep = new IfcSchema::IfcShapeRepresentation(context, std::string("Body"), std::string("BoundingBox"), items);
BRepBndLib::AddClose(i.Shape(), box); IfcSchema::IfcRepresentation::list::ptr new_reps(new IfcSchema::IfcRepresentation::list);
} new_reps->push(rep);
});
box.Add(gp_Pnt(0, 0, 0)); IfcSchema::IfcProductDefinitionShape* new_def = new IfcSchema::IfcProductDefinitionShape(boost::none, boost::none, new_reps);
double x1, y1, z1, x2, y2, z2; corner->data().isWritable()->setId(id++);
box.Get(x1, y1, z1, x2, y2, z2);
IfcSchema::IfcCartesianPoint* corner = new IfcSchema::IfcCartesianPoint(std::vector<double>{x1, y1, z1});; // NB: Corner is added to existing definitions
IfcSchema::IfcBoundingBox* bbox = new IfcSchema::IfcBoundingBox(corner, x2-x1, y2-y1, z2-z1); old_defs.push_back(corner); ++num_points_added;
IfcSchema::IfcRepresentationItem::list::ptr items(new IfcSchema::IfcRepresentationItem::list); new_defs.push_back(bbox);
items->push(bbox); new_defs.push_back(rep);
new_defs.push_back(new_def);
IfcSchema::IfcShapeRepresentation* rep = new IfcSchema::IfcShapeRepresentation(context, std::string("Body"), std::string("BoundingBox"), items); }
IfcSchema::IfcRepresentation::list::ptr new_reps(new IfcSchema::IfcRepresentation::list); }
new_reps->push(rep);
IfcSchema::IfcProductDefinitionShape* new_def = new IfcSchema::IfcProductDefinitionShape(boost::none, boost::none, new_reps);
corner->data().isWritable()->setId(id++);
// NB: Corner is added to existing definitions
old_defs.push_back(corner); ++num_points_added;
new_defs.push_back(bbox);
new_defs.push_back(rep);
new_defs.push_back(new_def);
return new_def;
});
std::for_each(new_defs.begin(), new_defs.end(), [&id](auto new_def) { std::for_each(new_defs.begin(), new_defs.end(), [&id](auto new_def) {
new_def->data().isWritable()->setId(id++); new_def->data().isWritable()->setId(id++);