mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-28 19:27:10 +00:00
Some more compatibility and continue working on wrapper
This commit is contained in:
@@ -1514,40 +1514,44 @@ namespace latebound_access {
|
|||||||
|
|
||||||
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_range = [&f](const IfcParse::IfcFile::type_iterator_range_t& insts) {
|
auto delete_reversed = [&f](const aggregate_of_instance::ptr& insts) {
|
||||||
|
if (!insts) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Lists are traversed back to front as the list may be mutated when
|
// Lists are traversed back to front as the list may be mutated when
|
||||||
// instances are removed from the grouping by type.
|
// instances are removed from the grouping by type.
|
||||||
for (auto it = insts.first; it != insts.second; ++it) {
|
for (auto it = insts->end() - 1; it >= insts->begin(); --it) {
|
||||||
f.removeEntity(&**it);
|
IfcUtil::IfcBaseClass* const inst = *it;
|
||||||
|
f.removeEntity(inst);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Delete quantities
|
// Delete quantities
|
||||||
auto quantities = f.instances_by_type("IfcPhysicalQuantity");
|
auto quantities = f.instances_by_type("IfcPhysicalQuantity");
|
||||||
for (auto& q : boost::make_iterator_range(quantities)) {
|
if (quantities) {
|
||||||
// @todo test iterator invalidation
|
quantities = quantities->filtered({ f.schema()->declaration_by_name("IfcPhysicalComplexQuantity") });
|
||||||
if (q->declaration().name() == "IfcPhysicalComplexQuantity") {
|
delete_reversed(quantities);
|
||||||
f.removeEntity(&*q);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete complexes
|
// Delete complexes
|
||||||
delete_range(f.instances_by_type("IfcPhysicalComplexQuantity"));
|
delete_reversed(f.instances_by_type("IfcPhysicalComplexQuantity"));
|
||||||
|
|
||||||
auto element_quantities = f.instances_by_type("IfcElementQuantity");
|
auto element_quantities = f.instances_by_type("IfcElementQuantity");
|
||||||
|
|
||||||
// Capture relationship nodes
|
// Capture relationship nodes
|
||||||
std::vector<IfcUtil::IfcBaseClass*> relationships;
|
std::vector<IfcUtil::IfcBaseClass*> relationships;
|
||||||
auto IfcRelDefinesByProperties = f.schema()->declaration_by_name("IfcRelDefinesByProperties");
|
auto IfcRelDefinesByProperties = f.schema()->declaration_by_name("IfcRelDefinesByProperties");
|
||||||
for (auto& eq : boost::make_iterator_range(element_quantities)) {
|
if (element_quantities) {
|
||||||
auto rels = eq->data().getInverse(IfcRelDefinesByProperties, -1);
|
for (auto& eq : *element_quantities) {
|
||||||
for (auto& rel : *rels) {
|
auto rels = eq->data().getInverse(IfcRelDefinesByProperties, -1);
|
||||||
relationships.push_back(rel);
|
for (auto& rel : *rels) {
|
||||||
|
relationships.push_back(rel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Delete element quantities
|
// Delete element quantities
|
||||||
delete_range(element_quantities);
|
delete_reversed(element_quantities);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Delete relationship nodes
|
// Delete relationship nodes
|
||||||
|
|||||||
+12
-6
@@ -232,7 +232,7 @@ class IFC_PARSE_API IfcFile {
|
|||||||
/// IfcWall will also return IfcWallStandardCase entities
|
/// IfcWall will also return IfcWallStandardCase entities
|
||||||
template <class T>
|
template <class T>
|
||||||
typename T::list::ptr instances_by_type() {
|
typename T::list::ptr instances_by_type() {
|
||||||
auto range = instances_by_type(&T::Class());
|
auto range = instances_by_type_range(&T::Class());
|
||||||
typename T::list::ptr vec(new typename T::list);
|
typename T::list::ptr vec(new typename T::list);
|
||||||
for (auto it = range.first; it != range.second; ++it) {
|
for (auto it = range.first; it != range.second; ++it) {
|
||||||
vec->push((*it)->template as<T>());
|
vec->push((*it)->template as<T>());
|
||||||
@@ -242,7 +242,7 @@ class IFC_PARSE_API IfcFile {
|
|||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
typename T::list::ptr instances_by_type_excl_subtypes() {
|
typename T::list::ptr instances_by_type_excl_subtypes() {
|
||||||
auto range = instances_by_type_excl_subtypes(&T::Class());
|
auto range = instances_by_type_excl_subtypes_range(&T::Class());
|
||||||
typename T::list::ptr vec(new typename T::list);
|
typename T::list::ptr vec(new typename T::list);
|
||||||
for (auto it = range.first; it != range.second; ++it) {
|
for (auto it = range.first; it != range.second; ++it) {
|
||||||
vec->push((*it)->template as<T>());
|
vec->push((*it)->template as<T>());
|
||||||
@@ -253,18 +253,24 @@ class IFC_PARSE_API IfcFile {
|
|||||||
/// Returns all entities in the file that match the positional argument.
|
/// Returns all entities in the file that match the positional argument.
|
||||||
/// NOTE: This also returns subtypes of the requested type, for example:
|
/// NOTE: This also returns subtypes of the requested type, for example:
|
||||||
/// IfcWall will also return IfcWallStandardCase entities
|
/// IfcWall will also return IfcWallStandardCase entities
|
||||||
type_iterator_range_t instances_by_type(const IfcParse::declaration*);
|
type_iterator_range_t instances_by_type_range(const IfcParse::declaration*);
|
||||||
|
|
||||||
/// Returns all entities in the file that match the positional argument.
|
/// Returns all entities in the file that match the positional argument.
|
||||||
type_iterator_range_t instances_by_type_excl_subtypes(const IfcParse::declaration*);
|
type_iterator_range_t instances_by_type_excl_subtypes_range(const IfcParse::declaration*);
|
||||||
|
|
||||||
/// Returns all entities in the file that match the positional argument.
|
/// Returns all entities in the file that match the positional argument.
|
||||||
/// NOTE: This also returns subtypes of the requested type, for example:
|
/// NOTE: This also returns subtypes of the requested type, for example:
|
||||||
/// IfcWall will also return IfcWallStandardCase entities
|
/// IfcWall will also return IfcWallStandardCase entities
|
||||||
type_iterator_range_t instances_by_type(const std::string& type);
|
type_iterator_range_t instances_by_type_range(const std::string& type);
|
||||||
|
|
||||||
/// Returns all entities in the file that match the positional argument.
|
/// Returns all entities in the file that match the positional argument.
|
||||||
type_iterator_range_t instances_by_type_excl_subtypes(const std::string& type);
|
type_iterator_range_t instances_by_type_excl_subtypes_range(const std::string& type);
|
||||||
|
|
||||||
|
/// Compatibility functions that take the ranges from above and turn into an aggregate
|
||||||
|
aggregate_of_instance::ptr instances_by_type(const IfcParse::declaration* decl);
|
||||||
|
aggregate_of_instance::ptr instances_by_type_excl_subtypes(const IfcParse::declaration* decl);
|
||||||
|
aggregate_of_instance::ptr instances_by_type(const std::string& type);
|
||||||
|
aggregate_of_instance::ptr instances_by_type_excl_subtypes(const std::string& type);
|
||||||
|
|
||||||
/// Returns all entities in the file that reference the id
|
/// Returns all entities in the file that reference the id
|
||||||
aggregate_of_instance::ptr instances_by_reference(int id);
|
aggregate_of_instance::ptr instances_by_reference(int id);
|
||||||
|
|||||||
@@ -2390,20 +2390,20 @@ void IfcFile::process_deletion_() {
|
|||||||
batch_deletion_ids_.clear();
|
batch_deletion_ids_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
IfcFile::type_iterator_range_t IfcFile::instances_by_type(const IfcParse::declaration* t) {
|
IfcFile::type_iterator_range_t IfcFile::instances_by_type_range(const IfcParse::declaration* t) {
|
||||||
return bytype_.equal_range(t);
|
return bytype_.equal_range(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
IfcFile::type_iterator_range_t IfcFile::instances_by_type_excl_subtypes(const IfcParse::declaration* t) {
|
IfcFile::type_iterator_range_t IfcFile::instances_by_type_excl_subtypes_range(const IfcParse::declaration* t) {
|
||||||
return bytype_.equal_range(t);
|
return bytype_.equal_range(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
IfcFile::type_iterator_range_t IfcFile::instances_by_type(const std::string& t) {
|
IfcFile::type_iterator_range_t IfcFile::instances_by_type_range(const std::string& t) {
|
||||||
return instances_by_type(schema()->declaration_by_name(t));
|
return instances_by_type_range(schema()->declaration_by_name(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
IfcFile::type_iterator_range_t IfcFile::instances_by_type_excl_subtypes(const std::string& t) {
|
IfcFile::type_iterator_range_t IfcFile::instances_by_type_excl_subtypes_range(const std::string& t) {
|
||||||
return instances_by_type_excl_subtypes(schema()->declaration_by_name(t));
|
return instances_by_type_excl_subtypes_range(schema()->declaration_by_name(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
aggregate_of_instance::ptr IfcFile::instances_by_reference(int t) {
|
aggregate_of_instance::ptr IfcFile::instances_by_reference(int t) {
|
||||||
@@ -2623,10 +2623,10 @@ void IfcFile::setDefaultHeaderValues() {
|
|||||||
std::pair<IfcUtil::IfcBaseClass*, double> IfcFile::getUnit(const std::string& unit_type) {
|
std::pair<IfcUtil::IfcBaseClass*, double> IfcFile::getUnit(const std::string& unit_type) {
|
||||||
std::pair<IfcUtil::IfcBaseClass*, double> return_value(0, 1.);
|
std::pair<IfcUtil::IfcBaseClass*, double> return_value(0, 1.);
|
||||||
|
|
||||||
auto projects = instances_by_type(schema()->declaration_by_name("IfcProject"));
|
auto projects = instances_by_type_range(schema()->declaration_by_name("IfcProject"));
|
||||||
if (std::distance(projects.first, projects.second) == 0) {
|
if (std::distance(projects.first, projects.second) == 0) {
|
||||||
try {
|
try {
|
||||||
projects = instances_by_type(schema()->declaration_by_name("IfcContext"));
|
projects = instances_by_type_range(schema()->declaration_by_name("IfcContext"));
|
||||||
} catch (IfcException& e) {
|
} catch (IfcException& e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2709,7 +2709,31 @@ void IfcParse::IfcFile::build_inverses() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Compatibility functions that take the ranges from above and turn into an aggregate
|
||||||
|
aggregate_of_instance::ptr IfcParse::IfcFile::instances_by_type(const IfcParse::declaration* decl) {
|
||||||
|
aggregate_of_instance::ptr aggr(new aggregate_of_instance);
|
||||||
|
for (auto& inst : boost::make_iterator_range(instances_by_type_range(decl))) {
|
||||||
|
aggr->push(&*inst);
|
||||||
|
}
|
||||||
|
return aggr;
|
||||||
|
}
|
||||||
|
aggregate_of_instance::ptr IfcParse::IfcFile::instances_by_type_excl_subtypes(const IfcParse::declaration* decl) {
|
||||||
|
aggregate_of_instance::ptr aggr(new aggregate_of_instance);
|
||||||
|
for (auto& inst : boost::make_iterator_range(instances_by_type_excl_subtypes_range(decl))) {
|
||||||
|
aggr->push(&*inst);
|
||||||
|
}
|
||||||
|
return aggr;
|
||||||
|
}
|
||||||
|
aggregate_of_instance::ptr IfcParse::IfcFile::instances_by_type(const std::string& type) {
|
||||||
|
return instances_by_type(schema()->declaration_by_name(type));
|
||||||
|
}
|
||||||
|
aggregate_of_instance::ptr IfcParse::IfcFile::instances_by_type_excl_subtypes(const std::string& type) {
|
||||||
|
return instances_by_type_excl_subtypes(schema()->declaration_by_name(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::atomic_uint32_t IfcUtil::IfcBaseClass::counter_(0);
|
std::atomic_uint32_t IfcUtil::IfcBaseClass::counter_(0);
|
||||||
|
|
||||||
bool IfcParse::IfcFile::lazy_load_ = true;
|
bool IfcParse::IfcFile::lazy_load_ = true;
|
||||||
bool IfcParse::IfcFile::guid_map_ = true;
|
bool IfcParse::IfcFile::guid_map_ = true;
|
||||||
|
|
||||||
|
|||||||
@@ -46,9 +46,9 @@ private:
|
|||||||
|
|
||||||
%ignore IfcUtil::IfcBaseClass::is;
|
%ignore IfcUtil::IfcBaseClass::is;
|
||||||
|
|
||||||
%rename("by_id") instance_by_id;
|
%ignore IfcParse::IfcFile::instance_by_id;
|
||||||
%rename("by_type") instances_by_type;
|
%ignore IfcParse::IfcFile::instances_by_type;
|
||||||
%rename("by_type_excl_subtypes") instances_by_type_excl_subtypes;
|
%ignore IfcParse::IfcFile::instances_by_type_excl_subtypes;
|
||||||
|
|
||||||
%rename("file") IfcFile;
|
%rename("file") IfcFile;
|
||||||
%ignore IfcParse::IfcFile::addEntity;
|
%ignore IfcParse::IfcFile::addEntity;
|
||||||
@@ -185,6 +185,28 @@ IfcUtil::ArgumentType helper_fn_attribute_type(const entity_instance* inst, unsi
|
|||||||
return $self->instance_by_guid(guid);
|
return $self->instance_by_guid(guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entity_instance by_id(int i) {
|
||||||
|
return $self->instance_by_id_2(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<entity_instance> by_type(const std::string& ty) {
|
||||||
|
std::vector<entity_instance> vec;
|
||||||
|
auto range = $self->instances_by_type_range(ty);
|
||||||
|
for (auto& inst : boost::make_iterator_range(range)) {
|
||||||
|
vec.push_back(inst);
|
||||||
|
}
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<entity_instance> by_type_excl_subtypes(const std::string& ty) {
|
||||||
|
std::vector<entity_instance> vec;
|
||||||
|
auto range = $self->instances_by_type_excl_subtypes_range(ty);
|
||||||
|
for (auto& inst : boost::make_iterator_range(range)) {
|
||||||
|
vec.push_back(inst);
|
||||||
|
}
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
entity_instance add(entity_instance& e, int i) {
|
entity_instance add(entity_instance& e, int i) {
|
||||||
return $self->addEntity(e, i);
|
return $self->addEntity(e, i);
|
||||||
}
|
}
|
||||||
@@ -405,13 +427,17 @@ IfcUtil::ArgumentType helper_fn_attribute_type(const entity_instance* inst, unsi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setArgumentAsNull(unsigned int i) {
|
void setAttribute(unsigned int i, PyObject* obj) {
|
||||||
bool is_optional = $self->declaration().as_entity()->attribute_by_index(i)->optional();
|
bool is_optional = $self->declaration().as_entity()->attribute_by_index(i)->optional();
|
||||||
|
|
||||||
|
if ()
|
||||||
if (is_optional) {
|
if (is_optional) {
|
||||||
self->data().setArgument(i, new IfcWrite::IfcWriteArgument());
|
self->data().setArgument(i, new IfcWrite::IfcWriteArgument());
|
||||||
} else {
|
} else {
|
||||||
throw IfcParse::IfcException("Attribute not set");
|
throw IfcParse::IfcException("Attribute not set");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setArgumentAsInt(unsigned int i, int v) {
|
void setArgumentAsInt(unsigned int i, int v) {
|
||||||
|
|||||||
@@ -1,11 +1,3 @@
|
|||||||
%typemap(out) aggregate_of_instance::ptr {
|
|
||||||
const unsigned size = $1 ? $1->size() : 0;
|
|
||||||
$result = PyTuple_New(size);
|
|
||||||
for (unsigned i = 0; i < size; ++i) {
|
|
||||||
PyTuple_SetItem($result, i, pythonize((*$1)[i]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
%typemap(out) IfcUtil::ArgumentType {
|
%typemap(out) IfcUtil::ArgumentType {
|
||||||
$result = SWIG_Python_str_FromChar(IfcUtil::ArgumentTypeToString($1));
|
$result = SWIG_Python_str_FromChar(IfcUtil::ArgumentTypeToString($1));
|
||||||
}
|
}
|
||||||
@@ -141,7 +133,7 @@ CREATE_VECTOR_TYPEMAP_OUT(int)
|
|||||||
CREATE_VECTOR_TYPEMAP_OUT(unsigned int)
|
CREATE_VECTOR_TYPEMAP_OUT(unsigned int)
|
||||||
CREATE_VECTOR_TYPEMAP_OUT(double)
|
CREATE_VECTOR_TYPEMAP_OUT(double)
|
||||||
CREATE_VECTOR_TYPEMAP_OUT(std::string)
|
CREATE_VECTOR_TYPEMAP_OUT(std::string)
|
||||||
// CREATE_VECTOR_TYPEMAP_OUT(IfcGeom::Material)
|
CREATE_VECTOR_TYPEMAP_OUT(entity_instance)
|
||||||
CREATE_VECTOR_TYPEMAP_OUT(IfcParse::attribute const *)
|
CREATE_VECTOR_TYPEMAP_OUT(IfcParse::attribute const *)
|
||||||
CREATE_VECTOR_TYPEMAP_OUT(IfcParse::inverse_attribute const *)
|
CREATE_VECTOR_TYPEMAP_OUT(IfcParse::inverse_attribute const *)
|
||||||
CREATE_VECTOR_TYPEMAP_OUT(IfcParse::entity const *)
|
CREATE_VECTOR_TYPEMAP_OUT(IfcParse::entity const *)
|
||||||
|
|||||||
@@ -443,14 +443,14 @@ void GltfSerializer::setFile(IfcParse::IfcFile* f) {
|
|||||||
boost::optional<std::array<double, 3>> crs_x_axis;
|
boost::optional<std::array<double, 3>> crs_x_axis;
|
||||||
boost::optional<std::array<double, 3>> eastings_northings_elevation;
|
boost::optional<std::array<double, 3>> eastings_northings_elevation;
|
||||||
|
|
||||||
IfcParse::IfcFile::type_iterator_range_t coordops;
|
aggregate_of_instance::ptr coordops;
|
||||||
try {
|
try {
|
||||||
coordops = f->instances_by_type("IfcCoordinateOperation");
|
coordops = f->instances_by_type("IfcCoordinateOperation");
|
||||||
} catch (IfcParse::IfcException&) {
|
} catch (IfcParse::IfcException&) {
|
||||||
// Ignored. Schema likely doesn't support IfcCoordinateOperation.
|
// Ignored. Schema likely doesn't support IfcCoordinateOperation.
|
||||||
}
|
}
|
||||||
if (std::distance(coordops.first, coordops.second)) {
|
if (coordops) {
|
||||||
for (auto& coordop : boost::make_iterator_range(coordops)) {
|
for (auto& coordop : *coordops) {
|
||||||
IfcUtil::IfcBaseClass* source_crs = *coordop->as<IfcUtil::IfcBaseEntity>()->get("SourceCRS");
|
IfcUtil::IfcBaseClass* source_crs = *coordop->as<IfcUtil::IfcBaseEntity>()->get("SourceCRS");
|
||||||
if (source_crs->declaration().is("IfcGeometricRepresentationContext")) {
|
if (source_crs->declaration().is("IfcGeometricRepresentationContext")) {
|
||||||
IfcUtil::IfcBaseClass* target_crs = *coordop->as<IfcUtil::IfcBaseEntity>()->get("TargetCRS");
|
IfcUtil::IfcBaseClass* target_crs = *coordop->as<IfcUtil::IfcBaseEntity>()->get("TargetCRS");
|
||||||
@@ -486,9 +486,9 @@ void GltfSerializer::setFile(IfcParse::IfcFile* f) {
|
|||||||
if (!crs_epsg) {
|
if (!crs_epsg) {
|
||||||
auto sites = f->instances_by_type("IfcSite");
|
auto sites = f->instances_by_type("IfcSite");
|
||||||
|
|
||||||
if (std::distance(sites.first, sites.second)) {
|
if (sites && sites->size() == 1) {
|
||||||
auto lat_attr = (*sites.first)->as<IfcUtil::IfcBaseEntity>()->get("RefLatitude");
|
auto lat_attr = (*sites->begin())->as<IfcUtil::IfcBaseEntity>()->get("RefLatitude");
|
||||||
auto lon_attr = (*sites.first)->as<IfcUtil::IfcBaseEntity>()->get("RefLongitude");
|
auto lon_attr = (*sites->begin())->as<IfcUtil::IfcBaseEntity>()->get("RefLongitude");
|
||||||
|
|
||||||
if (!lat_attr->isNull() && !lon_attr->isNull()) {
|
if (!lat_attr->isNull() && !lon_attr->isNull()) {
|
||||||
std::vector<int> lat_dms = *lat_attr;
|
std::vector<int> lat_dms = *lat_attr;
|
||||||
@@ -521,8 +521,8 @@ void GltfSerializer::setFile(IfcParse::IfcFile* f) {
|
|||||||
|
|
||||||
auto contexts = f->instances_by_type_excl_subtypes("IfcGeometricRepresentationContext");
|
auto contexts = f->instances_by_type_excl_subtypes("IfcGeometricRepresentationContext");
|
||||||
|
|
||||||
if (std::distance(contexts.first, contexts.second)) {
|
if (contexts && contexts->size() > 0) {
|
||||||
auto context = (*contexts.first)->as<IfcUtil::IfcBaseEntity>();
|
auto context = (*contexts->begin())->as<IfcUtil::IfcBaseEntity>();
|
||||||
auto north_attr = context->get("TrueNorth");
|
auto north_attr = context->get("TrueNorth");
|
||||||
if (!north_attr->isNull()) {
|
if (!north_attr->isNull()) {
|
||||||
IfcUtil::IfcBaseClass* north = *north_attr;
|
IfcUtil::IfcBaseClass* north = *north_attr;
|
||||||
|
|||||||
@@ -1830,13 +1830,13 @@ void SvgSerializer::addTextAnnotations(const drawing_key& k) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<IfcParse::IfcFile::type_iterator_range_t> annotations;
|
aggregate_of_instance::ptr annotations;
|
||||||
if (file) {
|
if (file) {
|
||||||
annotations = file->instances_by_type("IfcAnnotation");
|
annotations = file->instances_by_type("IfcAnnotation");
|
||||||
}
|
}
|
||||||
if (annotations) {
|
if (annotations) {
|
||||||
for (auto& ann_ : boost::make_iterator_range(*annotations)) {
|
for (auto& ann_ : *annotations) {
|
||||||
auto ann = ann_->as<IfcUtil::IfcBaseEntity>();
|
auto ann = (IfcUtil::IfcBaseEntity*) ann_;
|
||||||
|
|
||||||
auto ot = ann->get("ObjectType");
|
auto ot = ann->get("ObjectType");
|
||||||
auto nm = ann->get("Name");
|
auto nm = ann->get("Name");
|
||||||
@@ -2072,48 +2072,50 @@ void SvgSerializer::finalize() {
|
|||||||
|
|
||||||
if (file && storey_height_display_ != SH_NONE && pln && std::abs(pln->Position().Direction().Z()) < 1.e-5) {
|
if (file && storey_height_display_ != SH_NONE && pln && std::abs(pln->Position().Direction().Z()) < 1.e-5) {
|
||||||
auto storeys = file->instances_by_type("IfcBuildingStorey");
|
auto storeys = file->instances_by_type("IfcBuildingStorey");
|
||||||
const double lu = file->getUnit("LENGTHUNIT").second;
|
if (storeys) {
|
||||||
for (auto& s : boost::make_iterator_range(storeys)) {
|
const double lu = file->getUnit("LENGTHUNIT").second;
|
||||||
auto storey = s->as<IfcUtil::IfcBaseEntity>();
|
for (auto& s : *storeys) {
|
||||||
auto a = storey->get("Elevation");
|
auto storey = (IfcUtil::IfcBaseEntity*) s;
|
||||||
if (!a->isNull()) {
|
auto a = storey->get("Elevation");
|
||||||
double elev = *a;
|
if (!a->isNull()) {
|
||||||
elev *= lu;
|
double elev = *a;
|
||||||
auto svg_name = nameElement(storey);
|
elev *= lu;
|
||||||
|
auto svg_name = nameElement(storey);
|
||||||
|
|
||||||
gp_Pln elev_pln(gp_Ax3(gp_Pnt(0, 0, elev), gp::DZ(), gp::DX()));
|
gp_Pln elev_pln(gp_Ax3(gp_Pnt(0, 0, elev), gp::DZ(), gp::DX()));
|
||||||
//, pln->Position().XDirection()));
|
//, pln->Position().XDirection()));
|
||||||
// auto ref_y = pln->Position().YDirection().XYZ().Dot(pln->Position().Location().XYZ());
|
// auto ref_y = pln->Position().YDirection().XYZ().Dot(pln->Position().Location().XYZ());
|
||||||
|
|
||||||
double x0, y0, z0, x1, y1, z1;
|
double x0, y0, z0, x1, y1, z1;
|
||||||
bnd_.Get(x0, y0, z0, x1, y1, z1);
|
bnd_.Get(x0, y0, z0, x1, y1, z1);
|
||||||
|
|
||||||
// @todo this is a hack in order to get the auto elevations (which are 0.1 offset from
|
// @todo this is a hack in order to get the auto elevations (which are 0.1 offset from
|
||||||
// the global bounding box) to include the storey height symbols.
|
// the global bounding box) to include the storey height symbols.
|
||||||
x0 -= 0.2;
|
x0 -= 0.2;
|
||||||
y0 -= 0.2;
|
y0 -= 0.2;
|
||||||
z0 -= 0.2;
|
z0 -= 0.2;
|
||||||
|
|
||||||
x1 += 0.2;
|
x1 += 0.2;
|
||||||
y1 += 0.2;
|
y1 += 0.2;
|
||||||
z1 += 0.2;
|
z1 += 0.2;
|
||||||
|
|
||||||
const double shll = storey_height_line_length_.get_value_or(2.);
|
const double shll = storey_height_line_length_.get_value_or(2.);
|
||||||
|
|
||||||
BRepBuilderAPI_MakeFace mf(elev_pln, x0 - shll, x1 + shll, y0 - shll, y1 + shll);
|
BRepBuilderAPI_MakeFace mf(elev_pln, x0 - shll, x1 + shll, y0 - shll, y1 + shll);
|
||||||
gp_Trsf trsf;
|
gp_Trsf trsf;
|
||||||
TopoDS_Compound C;
|
TopoDS_Compound C;
|
||||||
BRep_Builder B;
|
BRep_Builder B;
|
||||||
B.MakeCompound(C);
|
B.MakeCompound(C);
|
||||||
B.Add(C, mf.Face());
|
B.Add(C, mf.Face());
|
||||||
std::string name;
|
std::string name;
|
||||||
auto a2 = storey->get("Name");
|
auto a2 = storey->get("Name");
|
||||||
if (!a2->isNull()) {
|
if (!a2->isNull()) {
|
||||||
name = (std::string) *a2;
|
name = (std::string) *a2;
|
||||||
|
}
|
||||||
|
write(geometry_data{
|
||||||
|
C,{boost::none},trsf,storey,storey,elev,name,nameElement(storey)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
write(geometry_data{
|
|
||||||
C,{boost::none},trsf,storey,storey,elev,name,nameElement(storey)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2301,28 +2303,30 @@ void SvgSerializer::setFile(IfcParse::IfcFile* f) {
|
|||||||
file = f;
|
file = f;
|
||||||
|
|
||||||
auto storeys = f->instances_by_type("IfcBuildingStorey");
|
auto storeys = f->instances_by_type("IfcBuildingStorey");
|
||||||
if (std::distance(storeys.first, storeys.second)) {
|
if (!storeys || storeys->size() == 0) {
|
||||||
auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(file, geometry_settings_);
|
auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(file, geometry_settings_);
|
||||||
|
|
||||||
std::vector<const IfcParse::declaration*> to_derive_from;
|
std::vector<const IfcParse::declaration*> to_derive_from;
|
||||||
to_derive_from.push_back(f->schema()->declaration_by_name("IfcBuilding"));
|
to_derive_from.push_back(f->schema()->declaration_by_name("IfcBuilding"));
|
||||||
to_derive_from.push_back(f->schema()->declaration_by_name("IfcSite"));
|
to_derive_from.push_back(f->schema()->declaration_by_name("IfcSite"));
|
||||||
for (auto it = to_derive_from.begin(); it != to_derive_from.end(); ++it) {
|
for (auto it = to_derive_from.begin(); it != to_derive_from.end(); ++it) {
|
||||||
auto insts = f->instances_by_type(*it);
|
aggregate_of_instance::ptr insts = f->instances_by_type(*it);
|
||||||
for (auto& product_ : boost::make_iterator_range(insts)) {
|
if (insts) {
|
||||||
IfcUtil::IfcBaseEntity* product = product_->as<IfcUtil::IfcBaseEntity>();
|
for (auto jt = insts->begin(); jt != insts->end(); ++jt) {
|
||||||
if (!product->get("ObjectPlacement")->isNull()) {
|
IfcUtil::IfcBaseEntity* product = (IfcUtil::IfcBaseEntity*) *jt;
|
||||||
auto item = mapping->map(*product->get("ObjectPlacement"));
|
if (!product->get("ObjectPlacement")->isNull()) {
|
||||||
auto matrix = ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::matrix4>(item);
|
auto item = mapping->map(*product->get("ObjectPlacement"));
|
||||||
gp_Trsf trsf;
|
auto matrix = ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::matrix4>(item);
|
||||||
if (matrix) {
|
gp_Trsf trsf;
|
||||||
// @todo shouldn't this take into account configurable section height?
|
if (matrix) {
|
||||||
setSectionHeight(matrix->translation_part()(3) + 1.);
|
// @todo shouldn't this take into account configurable section height?
|
||||||
|
setSectionHeight(matrix->translation_part()(3) + 1.);
|
||||||
#ifdef TAXONOMY_USE_NAKED_PTR
|
#ifdef TAXONOMY_USE_NAKED_PTR
|
||||||
delete matrix;
|
delete matrix;
|
||||||
#endif
|
#endif
|
||||||
Logger::Warning("No building storeys encountered, used for reference:", product);
|
Logger::Warning("No building storeys encountered, used for reference:", product);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2348,9 +2352,9 @@ void SvgSerializer::setSectionHeightsFromStoreys(double offset) {
|
|||||||
section_data_.emplace();
|
section_data_.emplace();
|
||||||
auto storeys = file->instances_by_type("IfcBuildingStorey");
|
auto storeys = file->instances_by_type("IfcBuildingStorey");
|
||||||
const double lu = file->getUnit("LENGTHUNIT").second;
|
const double lu = file->getUnit("LENGTHUNIT").second;
|
||||||
if (std::distance(storeys.first, storeys.second)) {
|
if (storeys && storeys->size() > 0) {
|
||||||
for (auto& s : boost::make_iterator_range(storeys)) {
|
for (auto& s : *storeys) {
|
||||||
auto attr_value = s->as<IfcUtil::IfcBaseEntity>()->get("Elevation");
|
auto attr_value = ((IfcUtil::IfcBaseEntity*)s)->get("Elevation");
|
||||||
if (!attr_value->isNull()) {
|
if (!attr_value->isNull()) {
|
||||||
double elev;
|
double elev;
|
||||||
try {
|
try {
|
||||||
@@ -2362,7 +2366,7 @@ void SvgSerializer::setSectionHeightsFromStoreys(double offset) {
|
|||||||
if (!section_data_->empty()) {
|
if (!section_data_->empty()) {
|
||||||
boost::get<horizontal_plan>(section_data_->back()).next_elevation = elev * lu;
|
boost::get<horizontal_plan>(section_data_->back()).next_elevation = elev * lu;
|
||||||
}
|
}
|
||||||
section_data_->push_back(horizontal_plan{ s->as<IfcUtil::IfcBaseEntity>(), elev * lu, offset, std::numeric_limits<double>::infinity() });
|
section_data_->push_back(horizontal_plan{ (IfcUtil::IfcBaseEntity*)s, elev * lu, offset, std::numeric_limits<double>::infinity() });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user