mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-25 09:32:37 +00:00
Work on LOD use case
This commit is contained in:
+146
-79
@@ -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++);
|
||||||
|
|||||||
Reference in New Issue
Block a user