mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 06:58:56 +00:00
Work towards space boundaries fix
This commit is contained in:
@@ -143,6 +143,7 @@ bool file_exists(const std::string& filename) {
|
|||||||
static std::basic_stringstream<path_t::value_type> log_stream;
|
static std::basic_stringstream<path_t::value_type> log_stream;
|
||||||
void write_log(bool);
|
void write_log(bool);
|
||||||
void fix_quantities(IfcParse::IfcFile&, bool, bool, bool);
|
void fix_quantities(IfcParse::IfcFile&, bool, bool, bool);
|
||||||
|
void fix_spaceboundaries(IfcParse::IfcFile&, bool, bool, bool);
|
||||||
std::string format_duration(time_t start, time_t end);
|
std::string format_duration(time_t start, time_t end);
|
||||||
|
|
||||||
/// @todo make the filters non-global
|
/// @todo make the filters non-global
|
||||||
@@ -219,7 +220,9 @@ int main(int argc, char** argv) {
|
|||||||
po::options_description ifc_options("IFC options");
|
po::options_description ifc_options("IFC options");
|
||||||
ifc_options.add_options()
|
ifc_options.add_options()
|
||||||
("calculate-quantities", "Calculate or fix the physical quantity definitions "
|
("calculate-quantities", "Calculate or fix the physical quantity definitions "
|
||||||
"based on an interpretation of the geometry when exporting IFC");
|
"based on an interpretation of the geometry when exporting IFC")
|
||||||
|
("fix-space-boundaries", "Calculate or fix space boundary geometries "
|
||||||
|
"when exporting IFC");
|
||||||
|
|
||||||
int num_threads;
|
int num_threads;
|
||||||
|
|
||||||
@@ -577,6 +580,9 @@ int main(int argc, char** argv) {
|
|||||||
if (vmap.count("calculate-quantities")) {
|
if (vmap.count("calculate-quantities")) {
|
||||||
fix_quantities(*ifc_file, no_progress, quiet, stderr_progress);
|
fix_quantities(*ifc_file, no_progress, quiet, stderr_progress);
|
||||||
}
|
}
|
||||||
|
if (vmap.count("fix-space-boundaries")) {
|
||||||
|
fix_spaceboundaries(*ifc_file, no_progress, quiet, stderr_progress);
|
||||||
|
}
|
||||||
fs << *ifc_file;
|
fs << *ifc_file;
|
||||||
exit_code = EXIT_SUCCESS;
|
exit_code = EXIT_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
@@ -1171,6 +1177,222 @@ namespace latebound_access {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef Handle
|
||||||
|
#include "../ifcgeom/kernels/cgal/CgalKernel.h"
|
||||||
|
#include <CGAL/box_intersection_d.h>
|
||||||
|
#include <CGAL/minkowski_sum_3.h>
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T enlarge(const T& t, double d = 1.e-5) {
|
||||||
|
T::NT min[3];
|
||||||
|
T::NT max[3];
|
||||||
|
for (int i = 0; i < t.dimension(); ++i) {
|
||||||
|
min[i] = t.min_coord(i) - d;
|
||||||
|
max[i] = t.max_coord(i) + d;
|
||||||
|
}
|
||||||
|
return T(min, max, t.handle());
|
||||||
|
}
|
||||||
|
|
||||||
|
int convert_to_nef(cgal_shape_t& shape, CGAL::Nef_polyhedron_3<Kernel_>& result) {
|
||||||
|
if (!shape.is_valid()) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!shape.is_closed()) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
success = CGAL::Polygon_mesh_processing::triangulate_faces(shape);
|
||||||
|
} catch (...) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CGAL::Polygon_mesh_processing::does_self_intersect(shape)) {
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
result = CGAL::Nef_polyhedron_3<Kernel_>(shape);
|
||||||
|
} catch (...) {
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fix_spaceboundaries(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool stderr_progress) {
|
||||||
|
typedef std::vector<std::pair<IfcUtil::IfcBaseEntity*, CGAL::Nef_polyhedron_3<Kernel_>> > nefs_t;
|
||||||
|
typedef CGAL::Box_intersection_d::Box_with_handle_d<Kernel_::FT, 3, nefs_t::const_iterator> Box;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
std::vector<ifcopenshell::geometry::filter_t> spaces_and_walls = {
|
||||||
|
IfcGeom::entity_filter(true, false, {"IfcWall", "IfcSpace"})
|
||||||
|
};
|
||||||
|
|
||||||
|
ifcopenshell::geometry::Iterator context_iterator("cgal", settings, &f, spaces_and_walls);
|
||||||
|
|
||||||
|
if (!context_iterator.initialize()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto kernel = (ifcopenshell::geometry::kernels::CgalKernel*) context_iterator.converter().kernel();
|
||||||
|
auto cube = kernel->precision_cube();
|
||||||
|
|
||||||
|
size_t num_created = 0;
|
||||||
|
int old_progress = quiet ? 0 : -1;
|
||||||
|
|
||||||
|
std::vector<Box> boxes;
|
||||||
|
nefs_t nefs;
|
||||||
|
|
||||||
|
for (;; ++num_created) {
|
||||||
|
bool has_more = true;
|
||||||
|
if (num_created) {
|
||||||
|
has_more = context_iterator.next();
|
||||||
|
}
|
||||||
|
ifcopenshell::geometry::NativeElement* geom_object = nullptr;
|
||||||
|
if (has_more) {
|
||||||
|
geom_object = context_iterator.get_native();
|
||||||
|
}
|
||||||
|
if (!geom_object) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << geom_object->product()->data().toString();
|
||||||
|
auto sss = ss.str();
|
||||||
|
std::wcout << sss.c_str() << std::endl;
|
||||||
|
|
||||||
|
for (auto& g : geom_object->geometry()) {
|
||||||
|
auto s = ((ifcopenshell::geometry::CgalShape*) g.Shape())->shape();
|
||||||
|
const auto& m = g.Placement().components;
|
||||||
|
const auto& n = geom_object->transformation().data().components;
|
||||||
|
|
||||||
|
if (true || !m.isIdentity()) {
|
||||||
|
const cgal_placement_t trsf(
|
||||||
|
m(0, 0), m(0, 1), m(0, 2), m(0, 3),
|
||||||
|
m(1, 0), m(1, 1), m(1, 2), m(1, 3),
|
||||||
|
m(2, 0), m(2, 1), m(2, 2), m(2, 3));
|
||||||
|
|
||||||
|
const cgal_placement_t trsf2(
|
||||||
|
n(0, 0), n(0, 1), n(0, 2), n(0, 3),
|
||||||
|
n(1, 0), n(1, 1), n(1, 2), n(1, 3),
|
||||||
|
n(2, 0), n(2, 1), n(2, 2), n(2, 3));
|
||||||
|
|
||||||
|
// Apply transformation
|
||||||
|
for (auto &vertex : vertices(s)) {
|
||||||
|
vertex->point() = vertex->point().transform(trsf).transform(trsf2);
|
||||||
|
/*
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << vertex->point().cartesian(0);
|
||||||
|
auto sss = ss.str();
|
||||||
|
std::wcout << sss.c_str() << std::endl;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wcout << 1 << std::endl;
|
||||||
|
CGAL::Nef_polyhedron_3<Kernel_> nef;
|
||||||
|
auto c = convert_to_nef(s, nef);
|
||||||
|
if (c != 0) {
|
||||||
|
std::wcout << "Error " << c << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::wcout << 2 << std::endl;
|
||||||
|
nef = CGAL::minkowski_sum_3(nef, cube);
|
||||||
|
std::wcout << 3 << std::endl;
|
||||||
|
nefs.push_back({ geom_object->product(), nef });
|
||||||
|
std::wcout << 4 << std::endl;
|
||||||
|
|
||||||
|
Kernel_::RT inf(std::numeric_limits<double>::infinity());
|
||||||
|
Kernel_::RT min[3] = { +inf, +inf, +inf };
|
||||||
|
Kernel_::RT max[3] = { -inf, -inf, -inf };
|
||||||
|
Box b(min, max, nefs.end() - 1);
|
||||||
|
|
||||||
|
for (auto &vertex : vertices(s)) {
|
||||||
|
Kernel_::RT p[3] = {
|
||||||
|
vertex->point().cartesian(0),
|
||||||
|
vertex->point().cartesian(1),
|
||||||
|
vertex->point().cartesian(2)
|
||||||
|
};
|
||||||
|
b.extend(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
boxes.push_back(enlarge(b));
|
||||||
|
|
||||||
|
/*
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << geom_object->product()->data().toString() << std::endl << b.min_coord(0) << " - " << b.max_coord(0) << std::endl;
|
||||||
|
auto sss = ss.str();
|
||||||
|
std::wcout << sss.c_str();
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!no_progress) {
|
||||||
|
if (quiet) {
|
||||||
|
const int progress = context_iterator.progress();
|
||||||
|
for (; old_progress < progress; ++old_progress) {
|
||||||
|
std::cout << ".";
|
||||||
|
if (stderr_progress)
|
||||||
|
std::cerr << ".";
|
||||||
|
}
|
||||||
|
std::cout << std::flush;
|
||||||
|
if (stderr_progress)
|
||||||
|
std::cerr << std::flush;
|
||||||
|
} else {
|
||||||
|
const int progress = context_iterator.progress() / 2;
|
||||||
|
if (old_progress != progress) Logger::ProgressBar(progress);
|
||||||
|
old_progress = progress;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CGAL::box_self_intersection_d(boxes.begin(), boxes.end(), [](const Box& a, const Box& b) {
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << a.handle()->first->data().toString() << "x" << b.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);
|
||||||
|
for (auto& v : vertices(x_poly)) {
|
||||||
|
auto p = v->point();
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
ss << p.cartesian(i) << " ";
|
||||||
|
}
|
||||||
|
ss << std::endl;
|
||||||
|
}
|
||||||
|
ss << "---" << std::endl;
|
||||||
|
auto sss = ss.str();
|
||||||
|
std::wcout << sss.c_str();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!no_progress && quiet) {
|
||||||
|
for (; old_progress < 100; ++old_progress) {
|
||||||
|
std::cout << ".";
|
||||||
|
if (stderr_progress)
|
||||||
|
std::cerr << ".";
|
||||||
|
}
|
||||||
|
std::cout << std::flush;
|
||||||
|
if (stderr_progress)
|
||||||
|
std::cerr << std::flush;
|
||||||
|
} else {
|
||||||
|
Logger::Status("\rDone fixing space boundaries for " + boost::lexical_cast<std::string>(num_created) +
|
||||||
|
" objects ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void fix_quantities(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool stderr_progress) {
|
void fix_quantities(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool stderr_progress) {
|
||||||
{
|
{
|
||||||
auto delete_reversed = [&f](const IfcEntityList::ptr& insts) {
|
auto delete_reversed = [&f](const IfcEntityList::ptr& insts) {
|
||||||
|
|||||||
@@ -24,12 +24,12 @@ void ifcopenshell::geometry::impl::MappingFactoryImplementation::bind(const std:
|
|||||||
this->insert(std::make_pair(schema_name_lower, fn));
|
this->insert(std::make_pair(schema_name_lower, fn));
|
||||||
}
|
}
|
||||||
|
|
||||||
ifcopenshell::geometry::abstract_mapping* ifcopenshell::geometry::impl::MappingFactoryImplementation::construct(IfcParse::IfcFile* file) {
|
ifcopenshell::geometry::abstract_mapping* ifcopenshell::geometry::impl::MappingFactoryImplementation::construct(IfcParse::IfcFile* file, settings& s) {
|
||||||
const std::string schema_name_lower = boost::to_lower_copy(file->schema()->name());
|
const std::string schema_name_lower = boost::to_lower_copy(file->schema()->name());
|
||||||
std::map<std::string, ifcopenshell::geometry::impl::mapping_fn>::const_iterator it;
|
std::map<std::string, ifcopenshell::geometry::impl::mapping_fn>::const_iterator it;
|
||||||
it = this->find(schema_name_lower);
|
it = this->find(schema_name_lower);
|
||||||
if (it == end()) {
|
if (it == end()) {
|
||||||
throw IfcParse::IfcException("No geometry mapping registered for " + schema_name_lower);
|
throw IfcParse::IfcException("No geometry mapping registered for " + schema_name_lower);
|
||||||
}
|
}
|
||||||
return it->second(file);
|
return it->second(file, s);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,11 @@ namespace geometry {
|
|||||||
typedef boost::function<bool(IfcUtil::IfcBaseEntity*)> filter_t;
|
typedef boost::function<bool(IfcUtil::IfcBaseEntity*)> filter_t;
|
||||||
|
|
||||||
class abstract_mapping {
|
class abstract_mapping {
|
||||||
|
protected:
|
||||||
|
settings settings_;
|
||||||
public:
|
public:
|
||||||
|
abstract_mapping(settings& s) : settings_(s) {}
|
||||||
|
|
||||||
virtual ifcopenshell::geometry::taxonomy::item* map(const IfcUtil::IfcBaseClass*) = 0;
|
virtual ifcopenshell::geometry::taxonomy::item* map(const IfcUtil::IfcBaseClass*) = 0;
|
||||||
virtual void get_representations(std::vector<geometry_conversion_task>& tasks, std::vector<filter_t>& filters, settings& s) = 0;
|
virtual void get_representations(std::vector<geometry_conversion_task>& tasks, std::vector<filter_t>& filters, settings& s) = 0;
|
||||||
virtual IfcUtil::IfcBaseEntity* get_decomposing_entity(IfcUtil::IfcBaseEntity* product, bool include_openings = true) = 0;
|
virtual IfcUtil::IfcBaseEntity* get_decomposing_entity(IfcUtil::IfcBaseEntity* product, bool include_openings = true) = 0;
|
||||||
@@ -37,13 +41,13 @@ namespace geometry {
|
|||||||
};
|
};
|
||||||
|
|
||||||
namespace impl {
|
namespace impl {
|
||||||
typedef boost::function1<abstract_mapping*, IfcParse::IfcFile*> mapping_fn;
|
typedef boost::function2<abstract_mapping*, IfcParse::IfcFile*, settings&> mapping_fn;
|
||||||
|
|
||||||
class MappingFactoryImplementation : public std::map<std::string, mapping_fn> {
|
class MappingFactoryImplementation : public std::map<std::string, mapping_fn> {
|
||||||
public:
|
public:
|
||||||
MappingFactoryImplementation();
|
MappingFactoryImplementation();
|
||||||
void bind(const std::string& schema_name, mapping_fn);
|
void bind(const std::string& schema_name, mapping_fn);
|
||||||
abstract_mapping* construct(IfcParse::IfcFile*);
|
abstract_mapping* construct(IfcParse::IfcFile*, settings&);
|
||||||
};
|
};
|
||||||
|
|
||||||
MappingFactoryImplementation& mapping_implementations();
|
MappingFactoryImplementation& mapping_implementations();
|
||||||
|
|||||||
@@ -447,6 +447,24 @@ CGAL::Polyhedron_3<Kernel_> CgalKernel::create_cube(double d) {
|
|||||||
return create_polyhedron(face_list);
|
return create_polyhedron(face_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CgalKernel::thin_solid(const CGAL::Nef_polyhedron_3<Kernel_>& a, CGAL::Nef_polyhedron_3<Kernel_>& result) {
|
||||||
|
// @todo this should be possible as a minkowski sum of facet & cube. rather than a set of boolean ops.
|
||||||
|
|
||||||
|
auto a_nonconst = a;
|
||||||
|
auto ax = CGAL::minkowski_sum_3(a_nonconst, precision_cube_);
|
||||||
|
auto x = ax - a;
|
||||||
|
|
||||||
|
result = x;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
auto yxy = CGAL::minkowski_sum_3(x, precision_cube_);
|
||||||
|
auto y = yxy * a;
|
||||||
|
auto zyz = CGAL::minkowski_sum_3(y, precision_cube_);
|
||||||
|
result = yxy * zyz;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool CgalKernel::preprocess_boolean_operand(const IfcUtil::IfcBaseClass* log_reference, const cgal_shape_t& shape_const, CGAL::Nef_polyhedron_3<Kernel_>& result, bool dilate) {
|
bool CgalKernel::preprocess_boolean_operand(const IfcUtil::IfcBaseClass* log_reference, const cgal_shape_t& shape_const, CGAL::Nef_polyhedron_3<Kernel_>& result, bool dilate) {
|
||||||
cgal_shape_t shape = shape_const;
|
cgal_shape_t shape = shape_const;
|
||||||
|
|
||||||
@@ -589,7 +607,10 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result* br, ifcopenshell::
|
|||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cgal_shape_t a_poly;
|
cgal_shape_t a_poly, b_poly;
|
||||||
|
|
||||||
|
// CGAL::Nef_polyhedron_3<Kernel_> b;
|
||||||
|
// thin_solid(a, b);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
a.convert_to_polyhedron(a_poly);
|
a.convert_to_polyhedron(a_poly);
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ namespace kernels {
|
|||||||
|
|
||||||
CGAL::Polyhedron_3<Kernel_> create_cube(double d);
|
CGAL::Polyhedron_3<Kernel_> create_cube(double d);
|
||||||
bool preprocess_boolean_operand(const IfcUtil::IfcBaseClass* log_reference, const cgal_shape_t& shape_const, CGAL::Nef_polyhedron_3<Kernel_>& result, bool dilate);
|
bool preprocess_boolean_operand(const IfcUtil::IfcBaseClass* log_reference, const cgal_shape_t& shape_const, CGAL::Nef_polyhedron_3<Kernel_>& result, bool dilate);
|
||||||
|
bool thin_solid(const CGAL::Nef_polyhedron_3<Kernel_>& a, CGAL::Nef_polyhedron_3<Kernel_>& result);
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CgalKernel()
|
CgalKernel()
|
||||||
@@ -128,6 +129,8 @@ namespace kernels {
|
|||||||
virtual bool convert_impl(const taxonomy::shell*, ifcopenshell::geometry::ConversionResults&);
|
virtual bool convert_impl(const taxonomy::shell*, ifcopenshell::geometry::ConversionResults&);
|
||||||
virtual bool convert_impl(const taxonomy::extrusion*, ifcopenshell::geometry::ConversionResults&);
|
virtual bool convert_impl(const taxonomy::extrusion*, ifcopenshell::geometry::ConversionResults&);
|
||||||
virtual bool convert_impl(const taxonomy::boolean_result*, ifcopenshell::geometry::ConversionResults&);
|
virtual bool convert_impl(const taxonomy::boolean_result*, ifcopenshell::geometry::ConversionResults&);
|
||||||
|
|
||||||
|
const CGAL::Nef_polyhedron_3<Kernel_>& precision_cube() const { return precision_cube_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ using namespace ifcopenshell::geometry;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct POSTFIX_SCHEMA(factory_t) {
|
struct POSTFIX_SCHEMA(factory_t) {
|
||||||
abstract_mapping* operator()(IfcParse::IfcFile* file) const {
|
abstract_mapping* operator()(IfcParse::IfcFile* file, settings& settings) const {
|
||||||
ifcopenshell::geometry::POSTFIX_SCHEMA(mapping)* m = new ifcopenshell::geometry::POSTFIX_SCHEMA(mapping)(file);
|
ifcopenshell::geometry::POSTFIX_SCHEMA(mapping)* m = new ifcopenshell::geometry::POSTFIX_SCHEMA(mapping)(file, settings);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -321,7 +321,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcProduct* inst) {
|
|||||||
auto c = new taxonomy::collection;
|
auto c = new taxonomy::collection;
|
||||||
c->matrix = as<taxonomy::matrix4>(map(inst->ObjectPlacement()));
|
c->matrix = as<taxonomy::matrix4>(map(inst->ObjectPlacement()));
|
||||||
|
|
||||||
if (openings->size()) {
|
if (openings->size() && !settings_.get(settings::DISABLE_OPENING_SUBTRACTIONS)) {
|
||||||
auto ci = c->matrix.components.inverse();
|
auto ci = c->matrix.components.inverse();
|
||||||
|
|
||||||
IfcEntityList::ptr operands(new IfcEntityList);
|
IfcEntityList::ptr operands(new IfcEntityList);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace geometry {
|
|||||||
|
|
||||||
void initialize_units_();
|
void initialize_units_();
|
||||||
public:
|
public:
|
||||||
POSTFIX_SCHEMA(mapping)(IfcParse::IfcFile* file) : file_(file), placement_rel_to_(0) {
|
POSTFIX_SCHEMA(mapping)(IfcParse::IfcFile* file, settings& settings) : abstract_mapping(settings), file_(file), placement_rel_to_(0) {
|
||||||
initialize_units_();
|
initialize_units_();
|
||||||
}
|
}
|
||||||
virtual ifcopenshell::geometry::taxonomy::item* map(const IfcUtil::IfcBaseClass*);
|
virtual ifcopenshell::geometry::taxonomy::item* map(const IfcUtil::IfcBaseClass*);
|
||||||
|
|||||||
@@ -2,19 +2,21 @@
|
|||||||
|
|
||||||
#include "../../ifcgeom/schema_agnostic/IfcGeomElement.h"
|
#include "../../ifcgeom/schema_agnostic/IfcGeomElement.h"
|
||||||
|
|
||||||
ifcopenshell::geometry::Converter::Converter(const std::string& geometry_library, IfcParse::IfcFile* file) {
|
ifcopenshell::geometry::Converter::Converter(const std::string& geometry_library, IfcParse::IfcFile* file, settings& s)
|
||||||
|
: settings_(s)
|
||||||
|
{
|
||||||
kernel_ = kernels::construct(geometry_library, file);
|
kernel_ = kernels::construct(geometry_library, file);
|
||||||
mapping_ = impl::mapping_implementations().construct(file);
|
mapping_ = impl::mapping_implementations().construct(file, settings_);
|
||||||
}
|
}
|
||||||
|
|
||||||
ifcopenshell::geometry::NativeElement* ifcopenshell::geometry::Converter::create_brep_for_representation_and_product(
|
ifcopenshell::geometry::NativeElement* ifcopenshell::geometry::Converter::create_brep_for_representation_and_product(
|
||||||
const ifcopenshell::geometry::settings& settings, IfcUtil::IfcBaseEntity* representation, IfcUtil::IfcBaseEntity* product) {
|
IfcUtil::IfcBaseEntity* representation, IfcUtil::IfcBaseEntity* product) {
|
||||||
|
|
||||||
std::stringstream representation_id_builder;
|
std::stringstream representation_id_builder;
|
||||||
|
|
||||||
const std::string product_type = product->declaration().name();
|
const std::string product_type = product->declaration().name();
|
||||||
// @todo
|
// @todo
|
||||||
element_settings s(settings, 1.0 /*getValue(GV_LENGTH_UNIT) */, product_type);
|
element_settings s(settings_, 1.0 /*getValue(GV_LENGTH_UNIT) */, product_type);
|
||||||
|
|
||||||
int parent_id = -1;
|
int parent_id = -1;
|
||||||
try {
|
try {
|
||||||
@@ -210,7 +212,7 @@ ifcopenshell::geometry::NativeElement* ifcopenshell::geometry::Converter::create
|
|||||||
}
|
}
|
||||||
|
|
||||||
ifcopenshell::geometry::NativeElement* ifcopenshell::geometry::Converter::create_brep_for_processed_representation(
|
ifcopenshell::geometry::NativeElement* ifcopenshell::geometry::Converter::create_brep_for_processed_representation(
|
||||||
const ifcopenshell::geometry::settings& /* settings */, IfcUtil::IfcBaseEntity* /* representation */, IfcUtil::IfcBaseEntity* product,
|
IfcUtil::IfcBaseEntity* /* representation */, IfcUtil::IfcBaseEntity* product,
|
||||||
ifcopenshell::geometry::NativeElement* brep)
|
ifcopenshell::geometry::NativeElement* brep)
|
||||||
{
|
{
|
||||||
int parent_id = -1;
|
int parent_id = -1;
|
||||||
|
|||||||
@@ -17,8 +17,10 @@ namespace ifcopenshell { namespace geometry {
|
|||||||
private:
|
private:
|
||||||
abstract_mapping* mapping_;
|
abstract_mapping* mapping_;
|
||||||
kernels::AbstractKernel* kernel_;
|
kernels::AbstractKernel* kernel_;
|
||||||
|
ifcopenshell::geometry::settings settings_;
|
||||||
public:
|
public:
|
||||||
|
kernels::AbstractKernel* kernel() { return kernel_; }
|
||||||
|
|
||||||
// Tolerances and settings for various geometrical operations:
|
// Tolerances and settings for various geometrical operations:
|
||||||
enum GeomValue {
|
enum GeomValue {
|
||||||
// Specifies the deflection of the mesher
|
// Specifies the deflection of the mesher
|
||||||
@@ -49,7 +51,7 @@ namespace ifcopenshell { namespace geometry {
|
|||||||
GV_DIMENSIONALITY
|
GV_DIMENSIONALITY
|
||||||
};
|
};
|
||||||
|
|
||||||
Converter(const std::string& geometry_library, IfcParse::IfcFile* file);
|
Converter(const std::string& geometry_library, IfcParse::IfcFile* file, ifcopenshell::geometry::settings& settings);
|
||||||
|
|
||||||
~Converter() {}
|
~Converter() {}
|
||||||
|
|
||||||
@@ -81,8 +83,8 @@ namespace ifcopenshell { namespace geometry {
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
ifcopenshell::geometry::NativeElement* create_brep_for_representation_and_product(const ifcopenshell::geometry::settings& settings, IfcUtil::IfcBaseEntity* representation, IfcUtil::IfcBaseEntity* product);
|
ifcopenshell::geometry::NativeElement* create_brep_for_representation_and_product(IfcUtil::IfcBaseEntity* representation, IfcUtil::IfcBaseEntity* product);
|
||||||
ifcopenshell::geometry::NativeElement* create_brep_for_processed_representation(const ifcopenshell::geometry::settings& settings, IfcUtil::IfcBaseEntity* representation, IfcUtil::IfcBaseEntity* product, ifcopenshell::geometry::NativeElement* brep);
|
ifcopenshell::geometry::NativeElement* create_brep_for_processed_representation(IfcUtil::IfcBaseEntity* representation, IfcUtil::IfcBaseEntity* product, ifcopenshell::geometry::NativeElement* brep);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
static int count(const ifcopenshell::geometry::ConversionResultShape*, int, bool unique=false);
|
static int count(const ifcopenshell::geometry::ConversionResultShape*, int, bool unique=false);
|
||||||
|
|||||||
@@ -69,7 +69,9 @@ namespace IfcGeom {
|
|||||||
// @todo examine if this can indeed be static. For now usage is only
|
// @todo examine if this can indeed be static. For now usage is only
|
||||||
// in IfcConvert so invocation is bound to a single file with a single
|
// in IfcConvert so invocation is bound to a single file with a single
|
||||||
// schema.
|
// schema.
|
||||||
static auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(prod->data().file);
|
// @todo pass settings
|
||||||
|
ifcopenshell::geometry::settings s;
|
||||||
|
static auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(prod->data().file, s);
|
||||||
while ((parent = mapping->get_decomposing_entity(current, traverse_openings)) != nullptr) {
|
while ((parent = mapping->get_decomposing_entity(current, traverse_openings)) != nullptr) {
|
||||||
if (pred(parent)) {
|
if (pred(parent)) {
|
||||||
return true;
|
return true;
|
||||||
@@ -175,7 +177,9 @@ namespace IfcGeom {
|
|||||||
: wildcard_filter(include, traverse, patterns) {}
|
: wildcard_filter(include, traverse, patterns) {}
|
||||||
|
|
||||||
bool match(IfcUtil::IfcBaseEntity* prod) const {
|
bool match(IfcUtil::IfcBaseEntity* prod) const {
|
||||||
static auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(prod->data().file);
|
// @todo
|
||||||
|
ifcopenshell::geometry::settings s;
|
||||||
|
static auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(prod->data().file, s);
|
||||||
layer_map_t layers = mapping->get_layers(prod);
|
layer_map_t layers = mapping->get_layers(prod);
|
||||||
return std::find_if(layers.begin(), layers.end(), wildcards_match(values)) != layers.end();
|
return std::find_if(layers.begin(), layers.end(), wildcards_match(values)) != layers.end();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ namespace {
|
|||||||
{
|
{
|
||||||
IfcUtil::IfcBaseEntity* representation = rep->representation;
|
IfcUtil::IfcBaseEntity* representation = rep->representation;
|
||||||
IfcUtil::IfcBaseEntity* product = (IfcUtil::IfcBaseEntity*) *rep->products->begin();
|
IfcUtil::IfcBaseEntity* product = (IfcUtil::IfcBaseEntity*) *rep->products->begin();
|
||||||
auto brep = converter->create_brep_for_representation_and_product(settings, representation, product);
|
auto brep = converter->create_brep_for_representation_and_product(representation, product);
|
||||||
if (!brep) {
|
if (!brep) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -155,7 +155,7 @@ namespace {
|
|||||||
rep->elements = { elem };
|
rep->elements = { elem };
|
||||||
|
|
||||||
for (auto it = rep->products->begin() + 1; it != rep->products->end(); ++it) {
|
for (auto it = rep->products->begin() + 1; it != rep->products->end(); ++it) {
|
||||||
auto brep2 = converter->create_brep_for_processed_representation(settings, representation, (IfcUtil::IfcBaseEntity*) *it, brep);
|
auto brep2 = converter->create_brep_for_processed_representation(representation, (IfcUtil::IfcBaseEntity*) *it, brep);
|
||||||
if (brep2) {
|
if (brep2) {
|
||||||
auto elem2 = process_based_on_settings(settings, brep, dynamic_cast<ifcopenshell::geometry::TriangulationElement*>(elem));
|
auto elem2 = process_based_on_settings(settings, brep, dynamic_cast<ifcopenshell::geometry::TriangulationElement*>(elem));
|
||||||
if (elem2) {
|
if (elem2) {
|
||||||
@@ -209,7 +209,7 @@ namespace ifcopenshell { namespace geometry {
|
|||||||
const double unit_magnitude() const { return unit_magnitude_; }
|
const double unit_magnitude() const { return unit_magnitude_; }
|
||||||
|
|
||||||
bool initialize() {
|
bool initialize() {
|
||||||
converter_ = new Converter(geometry_library_, ifc_file);
|
converter_ = new Converter(geometry_library_, ifc_file, settings_);
|
||||||
converter_->mapping()->get_representations(tasks_, filters_, settings_);
|
converter_->mapping()->get_representations(tasks_, filters_, settings_);
|
||||||
|
|
||||||
if (tasks_.size() == 0) {
|
if (tasks_.size() == 0) {
|
||||||
@@ -243,7 +243,7 @@ namespace ifcopenshell { namespace geometry {
|
|||||||
std::vector<Converter*> kernel_pool;
|
std::vector<Converter*> kernel_pool;
|
||||||
kernel_pool.reserve(conc_threads);
|
kernel_pool.reserve(conc_threads);
|
||||||
for (unsigned i = 0; i < conc_threads; ++i) {
|
for (unsigned i = 0; i < conc_threads; ++i) {
|
||||||
kernel_pool.push_back(new Converter(geometry_library_, ifc_file));
|
kernel_pool.push_back(new Converter(geometry_library_, ifc_file, settings_));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::future<void>> threadpool;
|
std::vector<std::future<void>> threadpool;
|
||||||
@@ -377,6 +377,8 @@ namespace ifcopenshell { namespace geometry {
|
|||||||
const gp_XYZ& bounds_min() const { return bounds_min_; }
|
const gp_XYZ& bounds_min() const { return bounds_min_; }
|
||||||
const gp_XYZ& bounds_max() const { return bounds_max_; }
|
const gp_XYZ& bounds_max() const { return bounds_max_; }
|
||||||
|
|
||||||
|
Converter& converter() { return *converter_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Move to the next IfcRepresentation
|
// Move to the next IfcRepresentation
|
||||||
void _nextShape() {
|
void _nextShape() {
|
||||||
|
|||||||
@@ -472,7 +472,9 @@ std::string SvgSerializer::nameElement(const IfcUtil::IfcBaseEntity* elem) {
|
|||||||
void SvgSerializer::setFile(IfcParse::IfcFile* f) {
|
void SvgSerializer::setFile(IfcParse::IfcFile* f) {
|
||||||
file = f;
|
file = f;
|
||||||
|
|
||||||
mapping_ = ifcopenshell::geometry::impl::mapping_implementations().construct(f);
|
// @todo
|
||||||
|
ifcopenshell::geometry::settings s;
|
||||||
|
mapping_ = ifcopenshell::geometry::impl::mapping_implementations().construct(f, s);
|
||||||
|
|
||||||
auto storeys = f->instances_by_type("IfcBuildingStorey");
|
auto storeys = f->instances_by_type("IfcBuildingStorey");
|
||||||
if (!storeys || storeys->size() == 0) {
|
if (!storeys || storeys->size() == 0) {
|
||||||
|
|||||||
@@ -30,12 +30,14 @@
|
|||||||
class POSTFIX_SCHEMA(XmlSerializer) : public XmlSerializer {
|
class POSTFIX_SCHEMA(XmlSerializer) : public XmlSerializer {
|
||||||
private:
|
private:
|
||||||
IfcParse::IfcFile* file;
|
IfcParse::IfcFile* file;
|
||||||
|
// @todo
|
||||||
|
ifcopenshell::geometry::settings settings_;
|
||||||
ifcopenshell::geometry::abstract_mapping* mapping_;
|
ifcopenshell::geometry::abstract_mapping* mapping_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
POSTFIX_SCHEMA(XmlSerializer)(IfcParse::IfcFile* file, const std::string& xml_filename)
|
POSTFIX_SCHEMA(XmlSerializer)(IfcParse::IfcFile* file, const std::string& xml_filename)
|
||||||
: XmlSerializer(0, "")
|
: XmlSerializer(0, "")
|
||||||
, mapping_(ifcopenshell::geometry::impl::mapping_implementations().construct(file))
|
, mapping_(ifcopenshell::geometry::impl::mapping_implementations().construct(file, settings_))
|
||||||
{
|
{
|
||||||
this->file = file;
|
this->file = file;
|
||||||
this->xml_filename = xml_filename;
|
this->xml_filename = xml_filename;
|
||||||
|
|||||||
Reference in New Issue
Block a user