mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 18:16:40 +00:00
Track time; fixes for wall connectivity check
This commit is contained in:
@@ -946,14 +946,14 @@ void write_log(bool header) {
|
||||
}
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <chrono>
|
||||
|
||||
bool init_input_file(const std::string& filename, IfcParse::IfcFile*& ifc_file, bool no_progress, bool mmap) {
|
||||
time_t start, end;
|
||||
std::clock_t c_start = std::clock();
|
||||
|
||||
// Prevent IfcFile::Init() prints by setting output to null temporarily
|
||||
if (no_progress) { Logger::SetOutput(NULL, &log_stream); }
|
||||
|
||||
time(&start);
|
||||
#ifdef USE_MMAP
|
||||
ifc_file = new IfcParse::IfcFile(filename, mmap);
|
||||
#else
|
||||
@@ -970,10 +970,15 @@ bool init_input_file(const std::string& filename, IfcParse::IfcFile*& ifc_file,
|
||||
Logger::Error("Unable to parse input file '" + filename + "'");
|
||||
return false;
|
||||
}
|
||||
time(&end);
|
||||
|
||||
std::clock_t c_end = std::clock();
|
||||
|
||||
if (no_progress) { Logger::SetOutput(&cout_, &log_stream); }
|
||||
else { Logger::Status("Parsing input file took " + format_duration(start, end)); }
|
||||
else {
|
||||
std::stringstream ss;
|
||||
ss << std::setprecision(14) << (c_end - c_start) / (double)CLOCKS_PER_SEC;
|
||||
Logger::Status("total_ifc_parse_time " + ss.str());
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
@@ -1,25 +1,111 @@
|
||||
#include "validation_utils.h"
|
||||
|
||||
using namespace ifcopenshell::geometry;
|
||||
|
||||
#include <CGAL/AABB_tree.h>
|
||||
#include <CGAL/AABB_traits.h>
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
#include <CGAL/AABB_face_graph_triangle_primitive.h>
|
||||
|
||||
typedef Kernel_::FT FT;
|
||||
typedef Kernel_::Point_3 Point;
|
||||
typedef Kernel_::Segment_3 Segment;
|
||||
typedef CGAL::Polyhedron_3<Kernel_> Polyhedron;
|
||||
typedef CGAL::AABB_face_graph_triangle_primitive<Polyhedron> Primitive;
|
||||
typedef CGAL::AABB_traits<Kernel_, Primitive> Traits;
|
||||
typedef CGAL::AABB_tree<Traits> Tree;
|
||||
typedef Tree::Point_and_primitive_id Point_and_primitive_id;
|
||||
|
||||
void fix_spaceboundaries(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool stderr_progress) {
|
||||
intersection_validator v(f, { "IfcWall", "IfcSpace" }, no_progress, quiet, stderr_progress);
|
||||
intersection_validator v(f, { "IfcWall", "IfcSpace" }, 1.e-5, no_progress, quiet, stderr_progress);
|
||||
|
||||
auto rels = f.instances_by_type("IfcRelSpaceBoundary");
|
||||
|
||||
std::map<std::pair<const IfcUtil::IfcBaseClass*, const IfcUtil::IfcBaseClass*>, const IfcUtil::IfcBaseClass*> rel_by_space_elem;
|
||||
|
||||
|
||||
if (rels) {
|
||||
std::for_each(rels->begin(), rels->end(), [&rel_by_space_elem](const IfcUtil::IfcBaseClass* rel) {
|
||||
auto x = ((IfcUtil::IfcBaseEntity*)rel)->get_value<IfcUtil::IfcBaseClass*>("RelatingSpace");
|
||||
try {
|
||||
auto y = ((IfcUtil::IfcBaseEntity*)rel)->get_value<IfcUtil::IfcBaseClass*>("RelatedBuildingElement");
|
||||
rel_by_space_elem.insert({ { x,y }, rel });
|
||||
} catch (IfcParse::IfcException&) {
|
||||
// RelatedBuildingElement can be NULL
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
std::set<const IfcUtil::IfcBaseClass*> rels_encounted;
|
||||
|
||||
IfcParse::IfcFile f2("boundaries-triangulated.ifc");
|
||||
ifcopenshell::geometry::settings settings;
|
||||
|
||||
settings.set(ifcopenshell::geometry::settings::USE_WORLD_COORDS, false);
|
||||
settings.set(ifcopenshell::geometry::settings::WELD_VERTICES, false);
|
||||
settings.set(ifcopenshell::geometry::settings::SEW_SHELLS, true);
|
||||
settings.set(ifcopenshell::geometry::settings::CONVERT_BACK_UNITS, true);
|
||||
settings.set(ifcopenshell::geometry::settings::DISABLE_TRIANGULATION, true);
|
||||
settings.set(ifcopenshell::geometry::settings::DISABLE_OPENING_SUBTRACTIONS, true);
|
||||
|
||||
ifcopenshell::geometry::Converter c("cgal", &f2, settings);
|
||||
|
||||
std::map<std::set<std::string>, std::vector<Kernel_::Point_3>> elem_to_space_boundary_coords;
|
||||
|
||||
for (auto& i : *f2.instances_by_type("IfcProduct")) {
|
||||
auto n = ((IfcUtil::IfcBaseEntity*)i)->get_value<std::string>("Name");
|
||||
auto g1 = n.substr(0, 22);
|
||||
auto g2 = n.substr(23);
|
||||
auto item = c.mapping()->map(i);
|
||||
auto shell = (taxonomy::shell*) ((taxonomy::collection*)((taxonomy::collection*) item)->children[0])->children[0];
|
||||
for (auto& f : shell->children) {
|
||||
auto face = (taxonomy::face*) f;
|
||||
for (auto& w : face->children) {
|
||||
auto wire = (taxonomy::loop*) w;
|
||||
for (auto& e : wire->children) {
|
||||
auto edge = (taxonomy::edge*) e;
|
||||
auto p3 = boost::get<taxonomy::point3>(edge->start);
|
||||
auto p4 = ((taxonomy::geom_item*)item)->matrix.components * p3.components.homogeneous();
|
||||
Kernel_::Point_3 P(p4(0), p4(1), p4(2));
|
||||
elem_to_space_boundary_coords[{g1, g2}].emplace_back(P);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
v([](const intersection_validator::Box& a, const intersection_validator::Box& b) {
|
||||
v([&rel_by_space_elem, &elem_to_space_boundary_coords](const intersection_validator::Box& a, const intersection_validator::Box& b) {
|
||||
std::ostringstream ss;
|
||||
// ss << id_map[a.id()]->first->data().toString() << "x" << id_map[b.id()]->first->data().toString() << std::endl;
|
||||
// auto x = id_map[a.id()]->second * id_map[b.id()]->second;
|
||||
|
||||
ss << a.handle()->first->data().toString() << "x" << a.handle()->first->data().toString() << std::endl;
|
||||
auto x = a.handle()->second * b.handle()->second;
|
||||
cgal_shape_t x_poly;
|
||||
x.convert_to_polyhedron(x_poly);
|
||||
auto A = a.handle()->first;
|
||||
auto B = b.handle()->first;
|
||||
|
||||
CGAL::Polygon_mesh_processing::triangulate_faces(x_poly);
|
||||
auto Aguid = A->get_value<std::string>("GlobalId");
|
||||
auto Bguid = B->get_value<std::string>("GlobalId");
|
||||
|
||||
auto vs = vertices(x_poly);
|
||||
if (std::distance(vs.begin(), vs.end()) == 0) {
|
||||
int space_count = 0;
|
||||
if (A->declaration().name() == "IfcSpace") {
|
||||
space_count += 1;
|
||||
}
|
||||
if (B->declaration().name() == "IfcSpace") {
|
||||
space_count += 1;
|
||||
}
|
||||
if (space_count != 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
ss << a.handle()->first->data().toString() << "x" << a.handle()->first->data().toString() << std::endl;
|
||||
auto x = a.handle()->second * b.handle()->second;
|
||||
|
||||
if (x.is_empty()) {
|
||||
// std::wcout << "empty" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
cgal_shape_t x_poly;
|
||||
x.convert_to_polyhedron(x_poly);
|
||||
|
||||
auto s0 = a.handle()->first->declaration().name();
|
||||
auto s1 = b.handle()->first->declaration().name();
|
||||
auto i0 = a.handle()->first->data().id();
|
||||
@@ -30,6 +116,16 @@ void fix_spaceboundaries(IfcParse::IfcFile& f, bool no_progress, bool quiet, boo
|
||||
std::swap(i0, i1);
|
||||
}
|
||||
|
||||
Tree tree(faces(x_poly).first, faces(x_poly).second, x_poly);
|
||||
tree.accelerate_distance_queries();
|
||||
|
||||
for (auto& p : elem_to_space_boundary_coords[{Aguid, Bguid}]) {
|
||||
auto d = std::sqrt(CGAL::to_double(tree.squared_distance(p)));
|
||||
std::wcout << d << std::endl;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
{
|
||||
auto FN = s0 + "-" + s1 + "-" + std::to_string(i0) + "-" + std::to_string(i1) + "sb.off";
|
||||
|
||||
|
||||
@@ -46,12 +46,14 @@ void fix_storeycontainment(IfcParse::IfcFile& f, bool no_progress, bool quiet, b
|
||||
return get_elevation(a) < get_elevation(b);
|
||||
});
|
||||
|
||||
/*
|
||||
std::wcout << "Storeys ";
|
||||
for (auto& s : storeys_sorted) {
|
||||
auto n = ((IfcUtil::IfcBaseEntity*)s)->get_value<std::string>("Name");
|
||||
std::wcout << n.c_str() << " ";
|
||||
}
|
||||
std::wcout << std::endl;
|
||||
*/
|
||||
|
||||
std::vector<double> elevations;
|
||||
std::transform(storeys_sorted.begin(), storeys_sorted.end(), std::back_inserter(elevations), get_elevation);
|
||||
@@ -69,13 +71,14 @@ void fix_storeycontainment(IfcParse::IfcFile& f, bool no_progress, bool quiet, b
|
||||
|
||||
std::vector<CGAL::Nef_polyhedron_3<Kernel_>> nefs;
|
||||
std::transform(elevation_slices.begin(), elevation_slices.end(), std::back_inserter(nefs), [&LARGE](const std::pair<double, double>& p) {
|
||||
std::wcout << p.first << " - " << p.second << std::endl;
|
||||
// std::wcout << p.first << " - " << p.second << std::endl;
|
||||
Kernel_::Point_3 p1(-LARGE, -LARGE, p.first);
|
||||
Kernel_::Point_3 p2(+LARGE, +LARGE, p.second);
|
||||
auto poly = ifcopenshell::geometry::utils::create_cube(p1, p2);
|
||||
return ifcopenshell::geometry::utils::create_nef_polyhedron(poly);
|
||||
});
|
||||
|
||||
/*
|
||||
for (auto& n : nefs) {
|
||||
auto poly = ifcopenshell::geometry::utils::create_polyhedron(n);
|
||||
auto bounds = CGAL::Polygon_mesh_processing::bbox_3(poly);
|
||||
@@ -87,6 +90,7 @@ void fix_storeycontainment(IfcParse::IfcFile& f, bool no_progress, bool quiet, b
|
||||
}
|
||||
std::wcout << "---" << std::endl;
|
||||
}
|
||||
*/
|
||||
|
||||
if (!context_iterator.initialize()) {
|
||||
return;
|
||||
@@ -108,13 +112,15 @@ void fix_storeycontainment(IfcParse::IfcFile& f, bool no_progress, bool quiet, b
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
std::stringstream ss;
|
||||
ss << geom_object->product()->data().toString();
|
||||
auto sss = ss.str();
|
||||
std::wcout << sss.c_str() << std::endl;
|
||||
*/
|
||||
|
||||
if (elem_to_storey.find(geom_object->product()) == elem_to_storey.end()) {
|
||||
std::wcout << "not associated to storey" << std::endl;
|
||||
// std::wcout << "not associated to storey" << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -140,6 +146,7 @@ void fix_storeycontainment(IfcParse::IfcFile& f, bool no_progress, bool quiet, b
|
||||
vertex->point() = vertex->point().transform(trsf).transform(trsf2);
|
||||
}
|
||||
|
||||
/*
|
||||
{
|
||||
auto bounds = CGAL::Polygon_mesh_processing::bbox_3(s);
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
@@ -150,11 +157,12 @@ void fix_storeycontainment(IfcParse::IfcFile& f, bool no_progress, bool quiet, b
|
||||
}
|
||||
std::wcout << "---" << std::endl;
|
||||
}
|
||||
*/
|
||||
|
||||
CGAL::Nef_polyhedron_3<Kernel_> part_nef = ifcopenshell::geometry::utils::create_nef_polyhedron(s);
|
||||
|
||||
if (!part_nef.is_simple()) {
|
||||
std::wcout << "not simple" << std::endl;
|
||||
// std::wcout << "not simple" << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -166,18 +174,20 @@ void fix_storeycontainment(IfcParse::IfcFile& f, bool no_progress, bool quiet, b
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
std::wcout << "volumes: ";
|
||||
for (auto& v : intersection_volumes) {
|
||||
std::wcout << v << " ";
|
||||
}
|
||||
std::wcout << std::endl;
|
||||
*/
|
||||
|
||||
auto idx = std::max_element(intersection_volumes.begin(), intersection_volumes.end()) - intersection_volumes.begin();
|
||||
if (storeys_sorted[idx] != elem_to_storey[geom_object->product()]) {
|
||||
auto s = geom_object->product()->data().toString();
|
||||
auto s1 = storeys_sorted[idx]->data().toString();
|
||||
auto s2 = elem_to_storey[geom_object->product()]->data().toString();
|
||||
std::wcout << "Mismatch on " << s.c_str() << ": " << s1.c_str() << " vs " << s2.c_str() << std::endl;
|
||||
auto s = geom_object->product()->get_value<std::string>("GlobalId");
|
||||
auto s1 = ((IfcUtil::IfcBaseEntity*)storeys_sorted[idx])->get_value<std::string>("GlobalId");
|
||||
auto s2 = ((IfcUtil::IfcBaseEntity*)elem_to_storey[geom_object->product()])->get_value<std::string>("GlobalId");
|
||||
Logger::Error("Element " + s + " contained in " + s2 + " located on " + s1);
|
||||
}
|
||||
|
||||
if (!no_progress) {
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
#include "validation_utils.h"
|
||||
|
||||
#include <CGAL/Polygon_mesh_processing/bbox.h>
|
||||
#include <CGAL/Polygon_mesh_processing/measure.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace ifcopenshell::geometry;
|
||||
|
||||
void fix_wallconnectivity(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool stderr_progress) {
|
||||
intersection_validator v(f, { "IfcWall" }, no_progress, quiet, stderr_progress);
|
||||
intersection_validator v(f, { "IfcWall" }, 1.e-3, no_progress, quiet, stderr_progress);
|
||||
|
||||
|
||||
ifcopenshell::geometry::settings settings;
|
||||
@@ -31,7 +34,10 @@ void fix_wallconnectivity(IfcParse::IfcFile& f, bool no_progress, bool quiet, bo
|
||||
|
||||
std::set<const IfcUtil::IfcBaseClass*> rels_encounted;
|
||||
|
||||
v([&c, &rel_by_elem, &rels_encounted](const intersection_validator::Box& a, const intersection_validator::Box& b) {
|
||||
double total_nef_intersection_time = 0.;
|
||||
double conversion_to_poly = 0.;
|
||||
|
||||
v([&c, &rel_by_elem, &rels_encounted, &total_nef_intersection_time, &conversion_to_poly](const intersection_validator::Box& a, const intersection_validator::Box& b) {
|
||||
auto A = a.handle()->first;
|
||||
auto B = b.handle()->first;
|
||||
|
||||
@@ -72,13 +78,33 @@ void fix_wallconnectivity(IfcParse::IfcFile& f, bool no_progress, bool quiet, bo
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << A->data().toString() << "x" << B->data().toString() << std::endl;
|
||||
std::clock_t intersection_begin = std::clock();
|
||||
auto x = a.handle()->second * b.handle()->second;
|
||||
std::clock_t intersection_end = std::clock();
|
||||
|
||||
total_nef_intersection_time += (intersection_end - intersection_begin) / (double) CLOCKS_PER_SEC;
|
||||
|
||||
if (x.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::clock_t poly_begin = std::clock();
|
||||
cgal_shape_t x_poly;
|
||||
x.convert_to_polyhedron(x_poly);
|
||||
std::clock_t poly_end = std::clock();
|
||||
conversion_to_poly += (poly_end - poly_begin) / (double)CLOCKS_PER_SEC;
|
||||
|
||||
auto dza = a.bbox().zmax() - a.bbox().zmin();
|
||||
auto dzb = b.bbox().zmax() - b.bbox().zmin();
|
||||
auto bb = CGAL::Polygon_mesh_processing::bbox_3(x_poly);
|
||||
if (bb.zmax() - bb.zmin() < std::min(dza, dzb) / 3.) {
|
||||
return;
|
||||
}
|
||||
|
||||
CGAL::Polygon_mesh_processing::triangulate_faces(x_poly);
|
||||
if (CGAL::Polygon_mesh_processing::area(x_poly) > 2.0) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto get_axis_parameter_min_max = [&c, &x_poly](IfcUtil::IfcBaseEntity* inst) {
|
||||
auto item = c.mapping()->map(inst);
|
||||
@@ -86,13 +112,13 @@ void fix_wallconnectivity(IfcParse::IfcFile& f, bool no_progress, bool quiet, bo
|
||||
auto loop = ((taxonomy::collection*) shaperep)->children[0];
|
||||
|
||||
if (loop->kind() != taxonomy::LOOP) {
|
||||
std::wcout << "no suitable axis" << std::endl;
|
||||
// std::wcout << "no suitable axis" << std::endl;
|
||||
} else {
|
||||
auto first_vertex = ((taxonomy::edge*) ((taxonomy::loop*) loop)->children.front())->start;
|
||||
auto last_vertex = ((taxonomy::edge*) ((taxonomy::loop*) loop)->children.back())->end;
|
||||
|
||||
if (first_vertex.which() != 0 || last_vertex.which() != 0) {
|
||||
std::wcout << "trims not supported" << std::endl;
|
||||
// std::wcout << "trims not supported" << std::endl;
|
||||
} else {
|
||||
auto p0 = boost::get<taxonomy::point3>(first_vertex);
|
||||
auto p1 = boost::get<taxonomy::point3>(last_vertex);
|
||||
@@ -114,7 +140,7 @@ void fix_wallconnectivity(IfcParse::IfcFile& f, bool no_progress, bool quiet, bo
|
||||
});
|
||||
|
||||
auto pit = std::minmax_element(parameters.begin(), parameters.end());
|
||||
return std::make_pair(len, std::make_pair(CGAL::to_double(*pit.first), CGAL::to_double(*pit.first)));
|
||||
return std::make_pair(len, std::make_pair(CGAL::to_double(*pit.first), CGAL::to_double(*pit.second)));
|
||||
}
|
||||
}
|
||||
const auto& nan = std::numeric_limits<double>::quiet_NaN();
|
||||
@@ -122,9 +148,9 @@ void fix_wallconnectivity(IfcParse::IfcFile& f, bool no_progress, bool quiet, bo
|
||||
};
|
||||
|
||||
auto qualify_connection_type = [](double l, const std::pair<double, double>& p) {
|
||||
if (p.first < 1.e-5) {
|
||||
if (p.first < 1.e-3) {
|
||||
return "ATSTART";
|
||||
} else if (p.second > l - 1.e-5) {
|
||||
} else if (p.second > l - 1.e-3) {
|
||||
return "ATEND";
|
||||
} else {
|
||||
return "ATPATH";
|
||||
@@ -141,21 +167,32 @@ void fix_wallconnectivity(IfcParse::IfcFile& f, bool no_progress, bool quiet, bo
|
||||
|
||||
if (a_type != atype_computed || b_type != btype_computed) {
|
||||
if (rel) {
|
||||
auto rel_str = rel->data().toString();
|
||||
std::wcout << "ERROR: " << rel_str.c_str() << " " << atype_computed << " " << btype_computed << std::endl;
|
||||
Logger::Error(std::string("Connection type ") + atype_computed + " " + btype_computed + " for:", rel);
|
||||
} else {
|
||||
auto A_str = A->data().toString();
|
||||
auto B_str = B->data().toString();
|
||||
std::wcout << "ERROR: no rel " << A_str.c_str() << " x " << B_str.c_str() << " " << atype_computed << " " << btype_computed << std::endl;
|
||||
auto A_str = A->get_value<std::string>("GlobalId");
|
||||
auto B_str = B->get_value<std::string>("GlobalId");
|
||||
Logger::Error("No connection for adjacent " + A_str + " " + B_str);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
std::for_each(rels->begin(), rels->end(), [&rels_encounted](const IfcUtil::IfcBaseClass* rel) {
|
||||
std::for_each(rels->begin(), rels->end(), [&rels_encounted, &v](const IfcUtil::IfcBaseClass* rel) {
|
||||
if (rels_encounted.find(rel) == rels_encounted.end()) {
|
||||
auto rel_str = rel->data().toString();
|
||||
std::wcout << "ERROR: " << rel_str.c_str() << " not found" << std::endl;
|
||||
auto x = (IfcUtil::IfcBaseEntity*)((IfcUtil::IfcBaseEntity*)rel)->get_value<IfcUtil::IfcBaseClass*>("RelatingElement");
|
||||
auto y = (IfcUtil::IfcBaseEntity*)((IfcUtil::IfcBaseEntity*)rel)->get_value<IfcUtil::IfcBaseClass*>("RelatedElement");
|
||||
if (v.succesfully_processed.find(x) != v.succesfully_processed.end() && v.succesfully_processed.find(y) != v.succesfully_processed.end()) {
|
||||
Logger::Error("Connection for non-adjacent walls", rel);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
std::wcout << std::setprecision(14);
|
||||
std::wcout << "total_map_time " << v.total_map_time << std::endl;
|
||||
std::wcout << "total_geom_time " << v.total_geom_time << std::endl;
|
||||
std::wcout << "total_nef_time " << v.total_nef_time << std::endl;
|
||||
std::wcout << "total_minkowsky_time " << v.total_minkowsky_time << std::endl;
|
||||
std::wcout << "total_box_time " << v.total_box_time << std::endl;
|
||||
std::wcout << "total_nef_intersection_time " << total_nef_intersection_time << std::endl;
|
||||
std::wcout << "total_conversion_to_poly_time " << conversion_to_poly << std::endl;
|
||||
}
|
||||
|
||||
|
||||
@@ -421,7 +421,15 @@ struct intersection_validator {
|
||||
std::vector<Box> boxes;
|
||||
nefs_t nefs;
|
||||
|
||||
intersection_validator(IfcParse::IfcFile& f, std::initializer_list<std::string> entities, bool no_progress, bool quiet, bool stderr_progress) {
|
||||
double total_map_time = 0.;
|
||||
double total_geom_time = 0.;
|
||||
double total_nef_time = 0.;
|
||||
double total_minkowsky_time = 0.;
|
||||
double total_box_time = 0.;
|
||||
|
||||
std::set<IfcUtil::IfcBaseEntity*> succesfully_processed;
|
||||
|
||||
intersection_validator(IfcParse::IfcFile& f, std::initializer_list<std::string> entities, double eps, bool no_progress, bool quiet, bool stderr_progress) {
|
||||
|
||||
ifcopenshell::geometry::settings settings;
|
||||
settings.set(ifcopenshell::geometry::settings::USE_WORLD_COORDS, false);
|
||||
@@ -441,8 +449,7 @@ struct intersection_validator {
|
||||
return;
|
||||
}
|
||||
|
||||
auto kernel = (ifcopenshell::geometry::kernels::CgalKernel*) context_iterator.converter().kernel();
|
||||
auto cube = kernel->precision_cube();
|
||||
auto cube = ifcopenshell::geometry::utils::create_nef_polyhedron(ifcopenshell::geometry::utils::create_cube(eps));
|
||||
|
||||
size_t num_created = 0;
|
||||
int old_progress = quiet ? 0 : -1;
|
||||
@@ -485,13 +492,21 @@ struct intersection_validator {
|
||||
vertex->point() = vertex->point().transform(trsf).transform(trsf2);
|
||||
}
|
||||
|
||||
std::clock_t nef_begin = std::clock();
|
||||
CGAL::Nef_polyhedron_3<Kernel_> nef = ifcopenshell::geometry::utils::create_nef_polyhedron(s);
|
||||
std::clock_t nef_end = std::clock();
|
||||
total_nef_time += (nef_end - nef_begin) / (double) CLOCKS_PER_SEC;
|
||||
if (nef.is_empty()) {
|
||||
std::wcout << "Failed to create nef" << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
succesfully_processed.insert(geom_object->product());
|
||||
|
||||
nef = CGAL::minkowski_sum_3(nef, cube);
|
||||
std::clock_t minkowski_end = std::clock();
|
||||
total_minkowsky_time += (minkowski_end - nef_end) / (double) CLOCKS_PER_SEC;
|
||||
|
||||
std::wcout << "product: " << geom_object->product() << std::endl;
|
||||
nefs.push_back({ geom_object->product(), nef });
|
||||
|
||||
@@ -550,10 +565,16 @@ struct intersection_validator {
|
||||
" objects ");
|
||||
}
|
||||
|
||||
total_geom_time = context_iterator.converter().total_geom_time;
|
||||
total_map_time = context_iterator.converter().total_map_time;
|
||||
}
|
||||
|
||||
template <typename Fn>
|
||||
void operator()(Fn fn) {
|
||||
std::clock_t box_overlap_begin = std::clock();
|
||||
CGAL::box_self_intersection_d(boxes.begin(), boxes.end(), [](auto& x, auto& y) {});
|
||||
std::clock_t box_overlap_end = std::clock();
|
||||
total_box_time += (box_overlap_end - box_overlap_begin) / (double) CLOCKS_PER_SEC;
|
||||
CGAL::box_self_intersection_d(boxes.begin(), boxes.end(), fn);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -44,11 +44,16 @@ ifcopenshell::geometry::NativeElement* ifcopenshell::geometry::Converter::create
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
std::clock_t map_start = std::clock();
|
||||
|
||||
// @todo how to combine product_node and rep_item?
|
||||
auto product_node = (taxonomy::geom_item*) mapping_->map(product);
|
||||
if (product_node == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::clock_t geom_start = std::clock();
|
||||
|
||||
auto place = taxonomy::matrix4();
|
||||
std::swap(place, product_node->matrix);
|
||||
@@ -57,6 +62,11 @@ ifcopenshell::geometry::NativeElement* ifcopenshell::geometry::Converter::create
|
||||
|
||||
shape = new ifcopenshell::geometry::Representation::BRep(s, representation_id_builder.str(), shapes);
|
||||
|
||||
std::clock_t geom_end = std::clock();
|
||||
|
||||
total_map_time += (geom_start - map_start) / (double) CLOCKS_PER_SEC;
|
||||
total_geom_time += (geom_end - geom_start) / (double) CLOCKS_PER_SEC;
|
||||
|
||||
return new NativeElement(
|
||||
product->data().id(),
|
||||
parent_id,
|
||||
|
||||
@@ -76,10 +76,18 @@ namespace ifcopenshell { namespace geometry {
|
||||
}
|
||||
*/
|
||||
|
||||
double total_map_time = 0.;
|
||||
double total_geom_time = 0.;
|
||||
|
||||
ifcopenshell::geometry::ConversionResults convert(IfcUtil::IfcBaseClass* item) {
|
||||
std::clock_t map_start = std::clock();
|
||||
auto geom_item = mapping_->map(item);
|
||||
std::clock_t geom_start = std::clock();
|
||||
ifcopenshell::geometry::ConversionResults results;
|
||||
kernel_->convert(geom_item, results);
|
||||
std::clock_t geom_end = std::clock();
|
||||
total_map_time += (geom_start - map_start) / (double) CLOCKS_PER_SEC;
|
||||
total_geom_time += (geom_end - geom_start) / (double) CLOCKS_PER_SEC;
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user