This commit is contained in:
Thomas Krijnen
2024-08-14 12:34:42 +02:00
parent 054ccf9a05
commit debb0f5e59
51 changed files with 947 additions and 488 deletions
+6 -8
View File
@@ -1486,7 +1486,7 @@ namespace latebound_access {
enum_type->enumeration_items().end(),
t);
return set(inst, attr, IfcWrite::IfcWriteArgument::EnumerationReference(it - enum_type->enumeration_items().begin(), it->c_str()));
return set(inst, attr, EnumerationReference(enum_type, it - enum_type->enumeration_items().begin()));
}
template <typename T>
@@ -1495,19 +1495,17 @@ namespace latebound_access {
auto i = decl->attribute_index(attr);
auto attr_type = decl->attribute_by_index(i)->type_of_attribute();
if (attr_type->as_named_type() && attr_type->as_named_type()->declared_type()->as_enumeration_type() && !std::is_same<T, IfcWrite::IfcWriteArgument::EnumerationReference>::value) {
if (attr_type->as_named_type() && attr_type->as_named_type()->declared_type()->as_enumeration_type() && !std::is_same<T, EnumerationReference>::value) {
set_enumeration(inst, attr, attr_type->as_named_type()->declared_type()->as_enumeration_type(), t);
} else {
IfcWrite::IfcWriteArgument* a = new IfcWrite::IfcWriteArgument;
a->set(t);
inst->data().attributes()[i] = a;
inst->set_attribute_value(i, t);
}
}
IfcUtil::IfcBaseClass* create(IfcParse::IfcFile& f, const std::string& entity) {
auto decl = f.schema()->declaration_by_name(entity);
auto data = new IfcEntityInstanceData(decl);
auto inst = f.schema()->instantiate(data);
auto data = IfcEntityInstanceData(storage_t(decl->as_entity()->attribute_count()));
auto inst = f.schema()->instantiate(entity, std::move(data));
if (decl->is("IfcRoot")) {
IfcParse::IfcGlobalId guid;
latebound_access::set(inst, "GlobalId", (std::string) guid);
@@ -1547,7 +1545,7 @@ void fix_quantities(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool std
auto IfcRelDefinesByProperties = f.schema()->declaration_by_name("IfcRelDefinesByProperties");
if (element_quantities) {
for (auto& eq : *element_quantities) {
auto rels = eq->data().getInverse(IfcRelDefinesByProperties, -1);
auto rels = eq->file_->getInverse(eq->id(), IfcRelDefinesByProperties, -1);
for (auto& rel : *rels) {
relationships.push_back(rel);
}
+12 -12
View File
@@ -35,7 +35,7 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
auto place = place_;
representation_id_builder << representation_node->instance->data().id();
representation_id_builder << representation_node->instance->as<IfcUtil::IfcBaseEntity>()->id();
IfcGeom::Representation::BRep* shape;
IfcGeom::ConversionResults shapes;
@@ -137,7 +137,7 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
}
if (material_style_applied) {
representation_id_builder << "-material-" << single_material->data().id();
representation_id_builder << "-material-" << single_material->id();
}
if (settings_.get<ifcopenshell::geometry::settings::ForceSpaceTransparency>().has() && product->declaration().is("IfcSpace")) {
@@ -153,7 +153,7 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
try {
IfcUtil::IfcBaseEntity* parent_object = mapping_->get_decomposing_entity(product);
if (parent_object) {
parent_id = parent_object->data().id();
parent_id = parent_object->id();
}
} catch (const std::exception& e) {
Logger::Error(e);
@@ -171,7 +171,7 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
if (!settings_.get<ifcopenshell::geometry::settings::DisableOpeningSubtractions>().get() && openings && openings->size()) {
representation_id_builder << "-openings";
for (auto it = openings->begin(); it != openings->end(); ++it) {
representation_id_builder << "-" << (*it)->data().id();
representation_id_builder << "-" << (*it)->id();
}
IfcGeom::ConversionResults opened_shapes;
@@ -236,19 +236,19 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
// IfcShapeRepresentation.
const IfcUtil::IfcBaseEntity *representation = representation_node->instance->as<IfcUtil::IfcBaseEntity>();
auto representation_identifier = representation->get("RepresentationIdentifier");
if (!representation_identifier->isNull()) {
context_string = (std::string) *representation_identifier;
if (!representation_identifier.isNull()) {
context_string = (std::string) representation_identifier;
}
else {
IfcUtil::IfcBaseClass *context = (IfcUtil::IfcBaseClass *) *representation->get("ContextOfItems");
IfcUtil::IfcBaseClass *context = (IfcUtil::IfcBaseClass*)representation->get("ContextOfItems");
auto context_type = context->as<IfcUtil::IfcBaseEntity>()->get("ContextType");
if (!context_type->isNull()) {
context_string = (std::string) *context_type;
if (!context_type.isNull()) {
context_string = (std::string)context_type;
}
}
auto elem = new IfcGeom::BRepElement(
product->data().id(),
product->id(),
parent_id,
name,
product_type,
@@ -340,7 +340,7 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_process
try {
IfcUtil::IfcBaseEntity* parent_object = mapping_->get_decomposing_entity(product);
if (parent_object) {
parent_id = parent_object->data().id();
parent_id = parent_object->id();
}
} catch (const std::exception& e) {
Logger::Error(e);
@@ -352,7 +352,7 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_process
const std::string context_string = brep->context();
return new IfcGeom::BRepElement(
product->data().id(),
product->id(),
parent_id,
name,
product_type,
+5 -5
View File
@@ -73,12 +73,12 @@ namespace IfcGeom {
friend bool operator < (const Element& element1, const Element& element2) {
if (element1.type() == "IfcBuildingStorey" && element2.type() == "IfcBuildingStorey") {
size_t attr_index = element1.product()->declaration().attribute_index("Elevation");
Argument* elev_attr1 = element1.product()->data().getArgument(attr_index);
Argument* elev_attr2 = element2.product()->data().getArgument(attr_index);
auto elev_attr1 = element1.product()->data().get_attribute_value(attr_index);
auto elev_attr2 = element2.product()->data().get_attribute_value(attr_index);
if (!elev_attr1->isNull() && !elev_attr2->isNull()) {
double elev1 = *elev_attr1;
double elev2 = *elev_attr2;
if (!elev_attr1.isNull() && !elev_attr2.isNull()) {
double elev1 = elev_attr1;
double elev2 = elev_attr2;
return elev1 < elev2;
}
+4 -4
View File
@@ -76,7 +76,7 @@ namespace IfcGeom {
// schema.
// @todo pass settings
ifcopenshell::geometry::Settings s;
static auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(prod->data().file, s);
static auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(prod->file_, s);
while ((parent = mapping->get_decomposing_entity(current, traverse_openings)) != nullptr) {
if (pred(parent)) {
return true;
@@ -138,7 +138,7 @@ namespace IfcGeom {
std::string value(IfcUtil::IfcBaseEntity* prod) const {
try {
return (std::string) *prod->get(attribute_name);
return (std::string) prod->get(attribute_name);
} catch (...) {
// Either
// (a) not an attribute name for this entity instance
@@ -184,7 +184,7 @@ namespace IfcGeom {
bool match(IfcUtil::IfcBaseEntity* prod) const {
// @todo
ifcopenshell::geometry::Settings s;
static auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(prod->data().file, s);
static auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(prod->file_, s);
layer_map_t layers = mapping->get_layers(prod);
return std::find_if(layers.begin(), layers.end(), wildcards_match(values)) != layers.end();
}
@@ -255,7 +255,7 @@ namespace IfcGeom {
, instance_ids_(instance_ids) {}
bool match(IfcUtil::IfcBaseEntity* prod) const {
return instance_ids_.find(prod->data().id()) != instance_ids_.end();
return instance_ids_.find(prod->id()) != instance_ids_.end();
}
bool operator()(IfcUtil::IfcBaseEntity* prod) const {
+1 -1
View File
@@ -154,7 +154,7 @@ IfcGeom::Representation::Serialization::Serialization(const BRep& brep)
surface_styles_.push_back(clr(1));
surface_styles_.push_back(clr(2));
sid = it->Style().instance ? it->Style().instance->data().id() : -1;
sid = it->Style().instance ? it->Style().instance->as<IfcUtil::IfcBaseEntity>()->id() : -1;
} else {
surface_styles_.push_back(-1.);
surface_styles_.push_back(-1.);
+4 -4
View File
@@ -518,7 +518,7 @@ namespace IfcGeom {
Logger::SetProduct(product);
IfcGeom::BRepElement* brep = static_cast<IfcGeom::BRepElement*>(decorate_with_cache_(GeometrySerializer::READ_BREP, (std::string)*product->get("GlobalId"), std::to_string(representation->instance->data().id()), [kernel, settings, product, place, representation]() {
IfcGeom::BRepElement* brep = static_cast<IfcGeom::BRepElement*>(decorate_with_cache_(GeometrySerializer::READ_BREP, (std::string)product->get("GlobalId"), std::to_string(representation->instance->as<IfcUtil::IfcBaseEntity>()->id()), [kernel, settings, product, place, representation]() {
return kernel->create_brep_for_representation_and_product(representation, product, place);
}));
@@ -539,7 +539,7 @@ namespace IfcGeom {
const IfcUtil::IfcBaseEntity* product2 = p.first;
const auto& place2 = p.second;
IfcGeom::BRepElement* brep2 = static_cast<IfcGeom::BRepElement*>(decorate_with_cache_(GeometrySerializer::READ_BREP, (std::string)*product2->get("GlobalId"), std::to_string(representation->instance->data().id()), [kernel, settings, product2, place2, representation, brep]() {
IfcGeom::BRepElement* brep2 = static_cast<IfcGeom::BRepElement*>(decorate_with_cache_(GeometrySerializer::READ_BREP, (std::string)product2->get("GlobalId"), std::to_string(representation->instance->as<IfcUtil::IfcBaseEntity>()->id()), [kernel, settings, product2, place2, representation, brep]() {
return kernel->create_brep_for_processed_representation(product2, place2, brep);
}));
if (brep2) {
@@ -746,13 +746,13 @@ namespace IfcGeom {
instance_type = ifc_product->declaration().name();
if (ifc_product->declaration().is("IfcRoot")) {
product_guid = (std::string) *ifc_product->get("GlobalId");
product_guid = (std::string) ifc_product->get("GlobalId");
product_name = ifc_product->get_value<std::string>("Name", "");
}
auto parent_object = converter_->mapping()->get_decomposing_entity(ifc_product);
if (parent_object) {
parent_id = parent_object->data().id();
parent_id = parent_object->id();
}
// fails in case of IfcProject
+2
View File
@@ -30,8 +30,10 @@ namespace geometry {
Settings settings_;
bool use_caching_ = true;
public:
abstract_mapping(Settings& s) : settings_(s) {}
virtual ~abstract_mapping() {}
virtual ifcopenshell::geometry::taxonomy::ptr map(const IfcUtil::IfcBaseInterface*) = 0;
virtual void get_representations(std::vector<geometry_conversion_task>& tasks, std::vector<filter_t>& filters) = 0;
+5 -5
View File
@@ -767,7 +767,7 @@ bool CgalKernel::convert_impl(const taxonomy::shell::ptr shell, ConversionResult
return false;
}
results.emplace_back(ConversionResult(
shell->instance->data().id(),
shell->instance->as<IfcUtil::IfcBaseEntity>()->id(),
shell->matrix,
new CgalShape(shape),
shell->surface_style
@@ -788,7 +788,7 @@ bool CgalKernel::convert_impl(const taxonomy::solid::ptr solid, ConversionResult
return false;
}
results.emplace_back(ConversionResult(
solid->instance->data().id(),
solid->instance->as<IfcUtil::IfcBaseEntity>()->id(),
solid->matrix,
new CgalShape(shape),
solid->surface_style
@@ -938,7 +938,7 @@ bool CgalKernel::convert_impl(const taxonomy::extrusion::ptr extrusion, Conversi
return false;
}
results.emplace_back(ConversionResult(
extrusion->instance->data().id(),
extrusion->instance->as<IfcUtil::IfcBaseEntity>()->id(),
extrusion->matrix,
new CgalShape(shape),
extrusion->surface_style
@@ -1814,7 +1814,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result::ptr br, Conversion
}
return ConversionResult(
br->instance->data().id(),
br->instance->as<IfcUtil::IfcBaseEntity>()->id(),
br->matrix,
new CgalShape(shp),
br->surface_style ? br->surface_style : first_item_style
@@ -2047,7 +2047,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result::ptr br, Conversion
}
results.emplace_back(ConversionResult(
br->instance->data().id(),
br->instance->as<IfcUtil::IfcBaseEntity>()->id(),
br->matrix,
new CgalShape(a_poly),
br->surface_style ? br->surface_style : first_item_style
@@ -107,7 +107,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result::ptr br, Con
if (settings_.get<settings::DisableBooleanResult>().get()) {
results.emplace_back(IfcGeom::ConversionResult(
(int)br->instance->data().id(),
br->instance->as<IfcUtil::IfcBaseEntity>()->id(),
br->matrix,
new OpenCascadeShape(a),
br->surface_style ? br->surface_style : first_item_style
@@ -189,7 +189,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result::ptr br, Con
}
results.emplace_back(IfcGeom::ConversionResult(
(int) br->instance->data().id(),
br->instance->as<IfcUtil::IfcBaseEntity>()->id(),
br->matrix,
new OpenCascadeShape(a),
br->surface_style ? br->surface_style : first_item_style
@@ -78,7 +78,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::extrusion::ptr extrusion, I
}
results.emplace_back(ConversionResult(
extrusion->instance->data().id(),
extrusion->instance->as<IfcUtil::IfcBaseEntity>()->id(),
extrusion->matrix,
new OpenCascadeShape(shape),
extrusion->surface_style
+1 -1
View File
@@ -514,7 +514,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::face::ptr face, IfcGeom::Co
return false;
}
results.emplace_back(ConversionResult(
face->instance->data().id(),
face->instance->as<IfcUtil::IfcBaseEntity>()->id(),
new OpenCascadeShape(shape),
face->surface_style
));
+1 -1
View File
@@ -113,7 +113,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::loft::ptr loft, IfcGeom::Co
return false;
}
results.emplace_back(ConversionResult(
loft->instance->data().id(),
loft->instance->as<IfcUtil::IfcBaseEntity>()->id(),
loft->matrix,
new OpenCascadeShape(shape),
loft->surface_style
+2 -2
View File
@@ -363,7 +363,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::loop::ptr loop, IfcGeom::Co
}
results.emplace_back(ConversionResult(
loop->instance->data().id(),
loop->instance->as<IfcUtil::IfcBaseEntity>()->id(),
new OpenCascadeShape(shape),
loop->surface_style
));
@@ -374,7 +374,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::edge::ptr edge, IfcGeom::Co
TopoDS_Wire shape = boost::get<TopoDS_Wire>(convert_curve(edge));
results.emplace_back(ConversionResult(
edge->instance->data().id(),
edge->instance->as<IfcUtil::IfcBaseEntity>()->id(),
new OpenCascadeShape(shape),
edge->surface_style
));
+1 -1
View File
@@ -112,7 +112,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::shell::ptr shell, IfcGeom::
return false;
}
results.emplace_back(ConversionResult(
shell->instance->data().id(),
shell->instance->as<IfcUtil::IfcBaseEntity>()->id(),
shell->matrix,
new OpenCascadeShape(shape),
shell->surface_style
+1 -1
View File
@@ -107,7 +107,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::solid::ptr solid, IfcGeom::
return false;
}
results.emplace_back(ConversionResult(
solid->instance->data().id(),
solid->instance->as<IfcUtil::IfcBaseEntity>()->id(),
solid->matrix,
new OpenCascadeShape(shape),
solid->surface_style
@@ -148,7 +148,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::sweep_along_curve::ptr scs,
return false;
}
results.emplace_back(ConversionResult(
scs->instance->data().id(),
scs->instance->as<IfcUtil::IfcBaseEntity>()->id(),
scs->matrix,
new OpenCascadeShape(shape),
scs->surface_style
+1 -1
View File
@@ -85,7 +85,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeCurve* inst) {
}
if (pwfs.empty()) {
aggregate_of_instance::ptr profile = inst->data().getInverse(&IfcSchema::IfcProfileDef::Class(), -1);
aggregate_of_instance::ptr profile = inst->file_->getInverse(inst->id(), &IfcSchema::IfcProfileDef::Class(), -1);
const bool force_close = profile && profile->size() > 0;
loop->closed = force_close;
loop->instance = inst;
+1 -1
View File
@@ -67,7 +67,7 @@ double translate_if_param_value(const IfcSchema::IfcCurve* crv, IfcSchema::IfcCu
// We don't care whether length- or positive length measure.
return translate_to_length_measure(crv, *param);
} else {
return *val->data().getArgument(0);
return val->data().get_attribute_value(0);
}
}
+2 -2
View File
@@ -117,9 +117,9 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTrimmedCurve* inst) {
// or trimmed segment would be whether there are other curve segments or this
// is the only one.
boost::optional<size_t> num_segments;
auto segment = inst->data().getInverse(&IfcSchema::IfcCompositeCurveSegment::Class(), -1);
auto segment = inst->file_->getInverse(inst->id(), & IfcSchema::IfcCompositeCurveSegment::Class(), -1);
if (segment->size() == 1) {
auto comp = (*segment->begin())->data().getInverse(&IfcSchema::IfcCompositeCurve::Class(), -1);
auto comp = (*segment->begin())->file_->getInverse((*segment->begin())->id(), &IfcSchema::IfcCompositeCurve::Class(), -1);
if (comp->size() == 1) {
num_segments = (*comp->begin())->as<IfcSchema::IfcCompositeCurve>()->Segments()->size();
}
+10 -10
View File
@@ -59,7 +59,7 @@ IfcSchema::IfcProduct::list::ptr mapping::products_represented_by(const IfcSchem
// IfcProductRepresentation also lacks the INVERSE relation to IfcProduct
// Let's find the IfcProducts that reference the IfcProductRepresentation anyway
products->push((*it)->data().getInverse((&IfcSchema::IfcProduct::Class()), -1)->as<IfcSchema::IfcProduct>());
products->push((*it)->file_->getInverse((*it)->id(), &IfcSchema::IfcProduct::Class(), -1)->as<IfcSchema::IfcProduct>());
}
if (only_direct) {
@@ -81,13 +81,13 @@ IfcSchema::IfcProduct::list::ptr mapping::products_represented_by(const IfcSchem
continue;
}
IfcSchema::IfcRepresentation::list::ptr reps = item->data().getInverse((&IfcSchema::IfcRepresentation::Class()), -1)->as<IfcSchema::IfcRepresentation>();
IfcSchema::IfcRepresentation::list::ptr reps = item->file_->getInverse(item->id(), (&IfcSchema::IfcRepresentation::Class()), -1)->as<IfcSchema::IfcRepresentation>();
for (IfcSchema::IfcRepresentation::list::it jt = reps->begin(); jt != reps->end(); ++jt) {
IfcSchema::IfcRepresentation* rep = *jt;
if (rep->Items()->size() != 1) continue;
IfcSchema::IfcProductRepresentation::list::ptr prodreps_mapped = rep->OfProductRepresentation();
for (IfcSchema::IfcProductRepresentation::list::it kt = prodreps_mapped->begin(); kt != prodreps_mapped->end(); ++kt) {
IfcSchema::IfcProduct::list::ptr ps = (*kt)->data().getInverse((&IfcSchema::IfcProduct::Class()), -1)->as<IfcSchema::IfcProduct>();
IfcSchema::IfcProduct::list::ptr ps = (*kt)->file_->getInverse((*kt)->id(), (&IfcSchema::IfcProduct::Class()), -1)->as<IfcSchema::IfcProduct>();
products->push(ps);
}
}
@@ -273,7 +273,7 @@ const IfcUtil::IfcBaseEntity* mapping::get_product_type(const IfcUtil::IfcBaseEn
}
#endif
// Avoid segfault if RelatingType is unset.
if (rel->get("RelatingType")->isNull()){
if (rel->get("RelatingType").isNull()){
break;
return nullptr;
}
@@ -492,7 +492,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcMaterial* material) {
material_style->name = material->Name();
} else {
std::ostringstream oss;
oss << material->declaration().name() << "-" << material->data().id();
oss << material->declaration().name() << "-" << material->id();
material_style->name = oss.str();
}
return material_style;
@@ -522,7 +522,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcStyledItem* inst) {
} else {
std::ostringstream oss;
if (shading) {
oss << shading->declaration().name() << "-" << shading->data().id();
oss << shading->declaration().name() << "-" << shading->id();
} else {
oss << "-";
}
@@ -660,8 +660,8 @@ IfcUtil::IfcBaseEntity* mapping::get_decomposing_entity(const IfcUtil::IfcBaseEn
/* Parent decompositions to the RelatingObject */
if (!parent) {
aggregate_of_instance::ptr parents = product->data().getInverse((&IfcSchema::IfcRelAggregates::Class()), -1);
parents->push(product->data().getInverse((&IfcSchema::IfcRelNests::Class()), -1));
aggregate_of_instance::ptr parents = product->file_->getInverse(product->id(), (&IfcSchema::IfcRelAggregates::Class()), -1);
parents->push(product->file_->getInverse(product->id(), (&IfcSchema::IfcRelNests::Class()), -1));
for (aggregate_of_instance::it it = parents->begin(); it != parents->end(); ++it) {
IfcSchema::IfcRelDecomposes* decompose = (*it)->as<IfcSchema::IfcRelDecomposes>();
IfcUtil::IfcBaseEntity* ifc_objectdef;
@@ -794,11 +794,11 @@ void mapping::initialize_settings() {
// See if there is a context_id filter and whether the context is selected
if (settings_.get<settings::ContextIds>().has()) {
auto cids = settings_.get<settings::ContextIds>().get();
if (cids.find(context->data().id()) == cids.end()) {
if (cids.find(context->id()) == cids.end()) {
bool selected_sub_context = false;
auto subs = context->HasSubContexts();
for (auto& sub : *subs) {
if (cids.find(context->data().id()) != cids.end()) {
if (cids.find(context->id()) != cids.end()) {
selected_sub_context = true;
break;
}
+3 -1
View File
@@ -641,7 +641,9 @@ void ifcopenshell::geometry::taxonomy::trimmed_curve::print(std::ostream& o, int
}
if (this->instance) {
o << std::string(indent + 4, ' ') << this->instance->data().toString() << std::endl;
std::ostringstream oss;
this->instance->as<IfcUtil::IfcBaseClass>()->toString(oss);
o << std::string(indent + 4, ' ') << oss.str() << std::endl;
}
}
@@ -370,7 +370,7 @@ class Implementation(codegen.Base):
("IfcEntityInstanceData&& e",),
"",
),
("", "", constructor, "", ("%s v" % type_str,), "set_attribute_value(0, v);") if mapping.simple_type_parent(class_name) is None else \
("", "", constructor, "", ("%s v" % type_str,), ("set_attribute_value(0, v%s);" % ("->generalize()" if mapping.is_templated_list(type) else ""))) if mapping.simple_type_parent(class_name) is None else \
("v", "", constructor, "", ("%s v" % type_str,), ""),
("", "", templates.cast_function, type_str, (), simpletype_impl_cast),
),
+1 -1
View File
@@ -6376,7 +6376,7 @@ Ifc4::IfcPressureMeasure::operator double() const { return data_.get_attribute_v
const IfcParse::type_declaration& Ifc4::IfcPropertySetDefinitionSet::Class() { return *((IfcParse::type_declaration*)IFC4_types[738]); }
const IfcParse::type_declaration& Ifc4::IfcPropertySetDefinitionSet::declaration() const { return *((IfcParse::type_declaration*)IFC4_types[738]); }
Ifc4::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(IfcEntityInstanceData&& e) : IfcUtil::IfcBaseType(std::move(e)) { }
Ifc4::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(aggregate_of< ::Ifc4::IfcPropertySetDefinition >::ptr v) : IfcUtil::IfcBaseType() { set_attribute_value(0, v); }
Ifc4::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(aggregate_of< ::Ifc4::IfcPropertySetDefinition >::ptr v) : IfcUtil::IfcBaseType() { set_attribute_value(0, v->generalize()); }
Ifc4::IfcPropertySetDefinitionSet::operator aggregate_of< ::Ifc4::IfcPropertySetDefinition >::ptr() const { aggregate_of_instance::ptr es = data_.get_attribute_value(0); return es->as< ::Ifc4::IfcPropertySetDefinition >(); }
// Function implementations for IfcRadioActivityMeasure
+1 -1
View File
@@ -6457,7 +6457,7 @@ Ifc4x1::IfcPressureMeasure::operator double() const { return data_.get_attribute
const IfcParse::type_declaration& Ifc4x1::IfcPropertySetDefinitionSet::Class() { return *((IfcParse::type_declaration*)IFC4X1_types[759]); }
const IfcParse::type_declaration& Ifc4x1::IfcPropertySetDefinitionSet::declaration() const { return *((IfcParse::type_declaration*)IFC4X1_types[759]); }
Ifc4x1::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(IfcEntityInstanceData&& e) : IfcUtil::IfcBaseType(std::move(e)) { }
Ifc4x1::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(aggregate_of< ::Ifc4x1::IfcPropertySetDefinition >::ptr v) : IfcUtil::IfcBaseType() { set_attribute_value(0, v); }
Ifc4x1::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(aggregate_of< ::Ifc4x1::IfcPropertySetDefinition >::ptr v) : IfcUtil::IfcBaseType() { set_attribute_value(0, v->generalize()); }
Ifc4x1::IfcPropertySetDefinitionSet::operator aggregate_of< ::Ifc4x1::IfcPropertySetDefinition >::ptr() const { aggregate_of_instance::ptr es = data_.get_attribute_value(0); return es->as< ::Ifc4x1::IfcPropertySetDefinition >(); }
// Function implementations for IfcRadioActivityMeasure
+1 -1
View File
@@ -6646,7 +6646,7 @@ Ifc4x2::IfcPressureMeasure::operator double() const { return data_.get_attribute
const IfcParse::type_declaration& Ifc4x2::IfcPropertySetDefinitionSet::Class() { return *((IfcParse::type_declaration*)IFC4X2_types[774]); }
const IfcParse::type_declaration& Ifc4x2::IfcPropertySetDefinitionSet::declaration() const { return *((IfcParse::type_declaration*)IFC4X2_types[774]); }
Ifc4x2::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(IfcEntityInstanceData&& e) : IfcUtil::IfcBaseType(std::move(e)) { }
Ifc4x2::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(aggregate_of< ::Ifc4x2::IfcPropertySetDefinition >::ptr v) : IfcUtil::IfcBaseType() { set_attribute_value(0, v); }
Ifc4x2::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(aggregate_of< ::Ifc4x2::IfcPropertySetDefinition >::ptr v) : IfcUtil::IfcBaseType() { set_attribute_value(0, v->generalize()); }
Ifc4x2::IfcPropertySetDefinitionSet::operator aggregate_of< ::Ifc4x2::IfcPropertySetDefinition >::ptr() const { aggregate_of_instance::ptr es = data_.get_attribute_value(0); return es->as< ::Ifc4x2::IfcPropertySetDefinition >(); }
// Function implementations for IfcRadioActivityMeasure
+1 -1
View File
@@ -7350,7 +7350,7 @@ Ifc4x3::IfcPressureMeasure::operator double() const { return data_.get_attribute
const IfcParse::type_declaration& Ifc4x3::IfcPropertySetDefinitionSet::Class() { return *((IfcParse::type_declaration*)IFC4X3_types[826]); }
const IfcParse::type_declaration& Ifc4x3::IfcPropertySetDefinitionSet::declaration() const { return *((IfcParse::type_declaration*)IFC4X3_types[826]); }
Ifc4x3::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(IfcEntityInstanceData&& e) : IfcUtil::IfcBaseType(std::move(e)) { }
Ifc4x3::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(aggregate_of< ::Ifc4x3::IfcPropertySetDefinition >::ptr v) : IfcUtil::IfcBaseType() { set_attribute_value(0, v); }
Ifc4x3::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(aggregate_of< ::Ifc4x3::IfcPropertySetDefinition >::ptr v) : IfcUtil::IfcBaseType() { set_attribute_value(0, v->generalize()); }
Ifc4x3::IfcPropertySetDefinitionSet::operator aggregate_of< ::Ifc4x3::IfcPropertySetDefinition >::ptr() const { aggregate_of_instance::ptr es = data_.get_attribute_value(0); return es->as< ::Ifc4x3::IfcPropertySetDefinition >(); }
// Function implementations for IfcRadioActivityMeasure
+1 -1
View File
@@ -7350,7 +7350,7 @@ Ifc4x3_add1::IfcPressureMeasure::operator double() const { return data_.get_attr
const IfcParse::type_declaration& Ifc4x3_add1::IfcPropertySetDefinitionSet::Class() { return *((IfcParse::type_declaration*)IFC4X3_ADD1_types[828]); }
const IfcParse::type_declaration& Ifc4x3_add1::IfcPropertySetDefinitionSet::declaration() const { return *((IfcParse::type_declaration*)IFC4X3_ADD1_types[828]); }
Ifc4x3_add1::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(IfcEntityInstanceData&& e) : IfcUtil::IfcBaseType(std::move(e)) { }
Ifc4x3_add1::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(aggregate_of< ::Ifc4x3_add1::IfcPropertySetDefinition >::ptr v) : IfcUtil::IfcBaseType() { set_attribute_value(0, v); }
Ifc4x3_add1::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(aggregate_of< ::Ifc4x3_add1::IfcPropertySetDefinition >::ptr v) : IfcUtil::IfcBaseType() { set_attribute_value(0, v->generalize()); }
Ifc4x3_add1::IfcPropertySetDefinitionSet::operator aggregate_of< ::Ifc4x3_add1::IfcPropertySetDefinition >::ptr() const { aggregate_of_instance::ptr es = data_.get_attribute_value(0); return es->as< ::Ifc4x3_add1::IfcPropertySetDefinition >(); }
// Function implementations for IfcRadioActivityMeasure
+1 -1
View File
@@ -7350,7 +7350,7 @@ Ifc4x3_add2::IfcPressureMeasure::operator double() const { return data_.get_attr
const IfcParse::type_declaration& Ifc4x3_add2::IfcPropertySetDefinitionSet::Class() { return *((IfcParse::type_declaration*)IFC4X3_ADD2_types[828]); }
const IfcParse::type_declaration& Ifc4x3_add2::IfcPropertySetDefinitionSet::declaration() const { return *((IfcParse::type_declaration*)IFC4X3_ADD2_types[828]); }
Ifc4x3_add2::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(IfcEntityInstanceData&& e) : IfcUtil::IfcBaseType(std::move(e)) { }
Ifc4x3_add2::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(aggregate_of< ::Ifc4x3_add2::IfcPropertySetDefinition >::ptr v) : IfcUtil::IfcBaseType() { set_attribute_value(0, v); }
Ifc4x3_add2::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(aggregate_of< ::Ifc4x3_add2::IfcPropertySetDefinition >::ptr v) : IfcUtil::IfcBaseType() { set_attribute_value(0, v->generalize()); }
Ifc4x3_add2::IfcPropertySetDefinitionSet::operator aggregate_of< ::Ifc4x3_add2::IfcPropertySetDefinition >::ptr() const { aggregate_of_instance::ptr es = data_.get_attribute_value(0); return es->as< ::Ifc4x3_add2::IfcPropertySetDefinition >(); }
// Function implementations for IfcRadioActivityMeasure
+1 -1
View File
@@ -7333,7 +7333,7 @@ Ifc4x3_rc1::IfcPressureMeasure::operator double() const { return data_.get_attri
const IfcParse::type_declaration& Ifc4x3_rc1::IfcPropertySetDefinitionSet::Class() { return *((IfcParse::type_declaration*)IFC4X3_RC1_types[842]); }
const IfcParse::type_declaration& Ifc4x3_rc1::IfcPropertySetDefinitionSet::declaration() const { return *((IfcParse::type_declaration*)IFC4X3_RC1_types[842]); }
Ifc4x3_rc1::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(IfcEntityInstanceData&& e) : IfcUtil::IfcBaseType(std::move(e)) { }
Ifc4x3_rc1::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(aggregate_of< ::Ifc4x3_rc1::IfcPropertySetDefinition >::ptr v) : IfcUtil::IfcBaseType() { set_attribute_value(0, v); }
Ifc4x3_rc1::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(aggregate_of< ::Ifc4x3_rc1::IfcPropertySetDefinition >::ptr v) : IfcUtil::IfcBaseType() { set_attribute_value(0, v->generalize()); }
Ifc4x3_rc1::IfcPropertySetDefinitionSet::operator aggregate_of< ::Ifc4x3_rc1::IfcPropertySetDefinition >::ptr() const { aggregate_of_instance::ptr es = data_.get_attribute_value(0); return es->as< ::Ifc4x3_rc1::IfcPropertySetDefinition >(); }
// Function implementations for IfcRadioActivityMeasure
+1 -1
View File
@@ -7416,7 +7416,7 @@ Ifc4x3_rc2::IfcPressureMeasure::operator double() const { return data_.get_attri
const IfcParse::type_declaration& Ifc4x3_rc2::IfcPropertySetDefinitionSet::Class() { return *((IfcParse::type_declaration*)IFC4X3_RC2_types[849]); }
const IfcParse::type_declaration& Ifc4x3_rc2::IfcPropertySetDefinitionSet::declaration() const { return *((IfcParse::type_declaration*)IFC4X3_RC2_types[849]); }
Ifc4x3_rc2::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(IfcEntityInstanceData&& e) : IfcUtil::IfcBaseType(std::move(e)) { }
Ifc4x3_rc2::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(aggregate_of< ::Ifc4x3_rc2::IfcPropertySetDefinition >::ptr v) : IfcUtil::IfcBaseType() { set_attribute_value(0, v); }
Ifc4x3_rc2::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(aggregate_of< ::Ifc4x3_rc2::IfcPropertySetDefinition >::ptr v) : IfcUtil::IfcBaseType() { set_attribute_value(0, v->generalize()); }
Ifc4x3_rc2::IfcPropertySetDefinitionSet::operator aggregate_of< ::Ifc4x3_rc2::IfcPropertySetDefinition >::ptr() const { aggregate_of_instance::ptr es = data_.get_attribute_value(0); return es->as< ::Ifc4x3_rc2::IfcPropertySetDefinition >(); }
// Function implementations for IfcRadioActivityMeasure
+1 -1
View File
@@ -7437,7 +7437,7 @@ Ifc4x3_rc3::IfcPressureMeasure::operator double() const { return data_.get_attri
const IfcParse::type_declaration& Ifc4x3_rc3::IfcPropertySetDefinitionSet::Class() { return *((IfcParse::type_declaration*)IFC4X3_RC3_types[836]); }
const IfcParse::type_declaration& Ifc4x3_rc3::IfcPropertySetDefinitionSet::declaration() const { return *((IfcParse::type_declaration*)IFC4X3_RC3_types[836]); }
Ifc4x3_rc3::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(IfcEntityInstanceData&& e) : IfcUtil::IfcBaseType(std::move(e)) { }
Ifc4x3_rc3::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(aggregate_of< ::Ifc4x3_rc3::IfcPropertySetDefinition >::ptr v) : IfcUtil::IfcBaseType() { set_attribute_value(0, v); }
Ifc4x3_rc3::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(aggregate_of< ::Ifc4x3_rc3::IfcPropertySetDefinition >::ptr v) : IfcUtil::IfcBaseType() { set_attribute_value(0, v->generalize()); }
Ifc4x3_rc3::IfcPropertySetDefinitionSet::operator aggregate_of< ::Ifc4x3_rc3::IfcPropertySetDefinition >::ptr() const { aggregate_of_instance::ptr es = data_.get_attribute_value(0); return es->as< ::Ifc4x3_rc3::IfcPropertySetDefinition >(); }
// Function implementations for IfcRadioActivityMeasure
+1 -1
View File
@@ -7437,7 +7437,7 @@ Ifc4x3_rc4::IfcPressureMeasure::operator double() const { return data_.get_attri
const IfcParse::type_declaration& Ifc4x3_rc4::IfcPropertySetDefinitionSet::Class() { return *((IfcParse::type_declaration*)IFC4X3_RC4_types[834]); }
const IfcParse::type_declaration& Ifc4x3_rc4::IfcPropertySetDefinitionSet::declaration() const { return *((IfcParse::type_declaration*)IFC4X3_RC4_types[834]); }
Ifc4x3_rc4::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(IfcEntityInstanceData&& e) : IfcUtil::IfcBaseType(std::move(e)) { }
Ifc4x3_rc4::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(aggregate_of< ::Ifc4x3_rc4::IfcPropertySetDefinition >::ptr v) : IfcUtil::IfcBaseType() { set_attribute_value(0, v); }
Ifc4x3_rc4::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(aggregate_of< ::Ifc4x3_rc4::IfcPropertySetDefinition >::ptr v) : IfcUtil::IfcBaseType() { set_attribute_value(0, v->generalize()); }
Ifc4x3_rc4::IfcPropertySetDefinitionSet::operator aggregate_of< ::Ifc4x3_rc4::IfcPropertySetDefinition >::ptr() const { aggregate_of_instance::ptr es = data_.get_attribute_value(0); return es->as< ::Ifc4x3_rc4::IfcPropertySetDefinition >(); }
// Function implementations for IfcRadioActivityMeasure
+1 -1
View File
@@ -7350,7 +7350,7 @@ Ifc4x3_tc1::IfcPressureMeasure::operator double() const { return data_.get_attri
const IfcParse::type_declaration& Ifc4x3_tc1::IfcPropertySetDefinitionSet::Class() { return *((IfcParse::type_declaration*)IFC4X3_TC1_types[826]); }
const IfcParse::type_declaration& Ifc4x3_tc1::IfcPropertySetDefinitionSet::declaration() const { return *((IfcParse::type_declaration*)IFC4X3_TC1_types[826]); }
Ifc4x3_tc1::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(IfcEntityInstanceData&& e) : IfcUtil::IfcBaseType(std::move(e)) { }
Ifc4x3_tc1::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(aggregate_of< ::Ifc4x3_tc1::IfcPropertySetDefinition >::ptr v) : IfcUtil::IfcBaseType() { set_attribute_value(0, v); }
Ifc4x3_tc1::IfcPropertySetDefinitionSet::IfcPropertySetDefinitionSet(aggregate_of< ::Ifc4x3_tc1::IfcPropertySetDefinition >::ptr v) : IfcUtil::IfcBaseType() { set_attribute_value(0, v->generalize()); }
Ifc4x3_tc1::IfcPropertySetDefinitionSet::operator aggregate_of< ::Ifc4x3_tc1::IfcPropertySetDefinition >::ptr() const { aggregate_of_instance::ptr es = data_.get_attribute_value(0); return es->as< ::Ifc4x3_tc1::IfcPropertySetDefinition >(); }
// Function implementations for IfcRadioActivityMeasure
+7 -4
View File
@@ -88,7 +88,6 @@ class IFC_PARSE_API IfcBaseInterface {
class IFC_PARSE_API IfcBaseClass : public virtual IfcBaseInterface {
protected:
uint32_t identity_;
uint32_t id_;
static std::atomic_uint32_t counter_;
IfcEntityInstanceData data_;
@@ -98,10 +97,15 @@ class IFC_PARSE_API IfcBaseClass : public virtual IfcBaseInterface {
}
public:
uint32_t id_;
IfcParse::IfcFile* file_;
IfcBaseClass(IfcEntityInstanceData&& data) : identity_(counter_++),
data_(std::move(data)) {}
IfcBaseClass(IfcEntityInstanceData&& data)
: identity_(counter_++)
, data_(std::move(data))
, id_(0)
, file_(nullptr)
{}
const IfcEntityInstanceData& data() const { return data_; }
IfcEntityInstanceData& data() { return data_; }
@@ -120,7 +124,6 @@ class IFC_PARSE_API IfcBaseClass : public virtual IfcBaseInterface {
uint32_t id() const { return id_; }
std::string toString(bool upper = false) const;
void toString(std::ostream&, bool upper = false) const;
};
+124
View File
@@ -0,0 +1,124 @@
#include "IfcEntityInstanceData.h"
#include "IfcBaseClass.h"
// @todo is size() still needed?
class SizeVisitor {
public:
typedef int result_type;
int operator()(const Blank& /*i*/) const { return -1; }
int operator()(const Derived& /*i*/) const { return -1; }
int operator()(const int& /*i*/) const { return -1; }
int operator()(const bool& /*i*/) const { return -1; }
int operator()(const boost::logic::tribool& /*i*/) const { return -1; }
int operator()(const double& /*i*/) const { return -1; }
int operator()(const std::string& /*i*/) const { return -1; }
int operator()(const boost::dynamic_bitset<>& /*i*/) const { return -1; }
int operator()(const empty_aggregate_t&) const { return 0; }
int operator()(const empty_aggregate_of_aggregate_t&) const { return 0; }
int operator()(const std::vector<int>& i) const { return (int)i.size(); }
int operator()(const std::vector<double>& i) const { return (int)i.size(); }
int operator()(const std::vector<std::vector<int>>& i) const { return (int)i.size(); }
int operator()(const std::vector<std::vector<double>>& i) const { return (int)i.size(); }
int operator()(const std::vector<std::string>& i) const { return (int)i.size(); }
int operator()(const std::vector<boost::dynamic_bitset<>>& i) const { return (int)i.size(); }
int operator()(const EnumerationReference& /*i*/) const { return -1; }
int operator()(const IfcUtil::IfcBaseClass* const& /*i*/) const { return -1; }
int operator()(const aggregate_of_instance::ptr& i) const { return i->size(); }
int operator()(const aggregate_of_aggregate_of_instance::ptr& i) const { return i->size(); }
};
AttributeValue::operator int() const
{
return array_->get<int>(index_);
}
AttributeValue::operator bool() const
{
return array_->get<bool>(index_);
}
AttributeValue::operator double() const
{
return array_->get<double>(index_);
}
AttributeValue::operator boost::logic::tribool() const
{
return array_->get<boost::logic::tribool>(index_);
}
AttributeValue::operator std::string() const
{
if (array_->has<EnumerationReference>(index_)) {
// @todo this is silly, but the way things currently work,
// @todo also we don't really need to store a reference to the enumeration type, when this same type is already stored on the definition of the entity and no other value can be provided.
return array_->get<EnumerationReference>(index_).value();
}
return array_->get<std::string>(index_);
}
AttributeValue::operator boost::dynamic_bitset<>() const
{
return array_->get<boost::dynamic_bitset<>>(index_);
}
AttributeValue::operator IfcUtil::IfcBaseClass* () const
{
return array_->get<IfcUtil::IfcBaseClass*>(index_);
}
AttributeValue::operator std::vector<int>() const
{
return array_->get<std::vector<int>>(index_);
}
AttributeValue::operator std::vector<double>() const
{
return array_->get<std::vector<double>>(index_);
}
AttributeValue::operator std::vector<std::string>() const
{
return array_->get<std::vector<std::string>>(index_);
}
AttributeValue::operator std::vector<boost::dynamic_bitset<>>() const
{
return array_->get<std::vector<boost::dynamic_bitset<>>>(index_);
}
AttributeValue::operator boost::shared_ptr<aggregate_of_instance>() const
{
return array_->get<boost::shared_ptr<aggregate_of_instance>>(index_);
}
AttributeValue::operator std::vector<std::vector<int>>() const
{
return array_->get<std::vector<std::vector<int>>>(index_);
}
AttributeValue::operator std::vector<std::vector<double>>() const
{
return array_->get<std::vector<std::vector<double>>>(index_);
}
AttributeValue::operator boost::shared_ptr<aggregate_of_aggregate_of_instance>() const
{
return array_->get<boost::shared_ptr<aggregate_of_aggregate_of_instance>>(index_);
}
bool AttributeValue::isNull() const
{
return array_->has<Blank>(index_);
}
unsigned int AttributeValue::size() const
{
return array_->apply_visitor(SizeVisitor{}, index_);
}
IfcUtil::ArgumentType AttributeValue::type() const
{
return static_cast<IfcUtil::ArgumentType>(array_->index(index_));
}
+19 -9
View File
@@ -23,9 +23,12 @@
#include "ArgumentType.h"
#include "variantarray.h"
#include "aggregate_of_instance.h"
#include "IfcSchema.h"
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/logic/tribool.hpp>
#include <boost/dynamic_bitset.hpp>
class EnumerationReference {
private:
@@ -112,19 +115,22 @@ typedef VariantArray <
aggregate_of_aggregate_of_instance::ptr
> storage_t;
struct MutableAttributeValue {
int name_;
uint8_t index_;
};
// short lived
class AttributeValue {
private:
storage_t* array_;
struct AttributeValue {
const storage_t* array_;
uint8_t index_;
public:
AttributeValue()
: array_(nullptr)
, index_(0)
{}
AttributeValue(storage_t* arr, uint8_t index)
AttributeValue(const storage_t* arr, uint8_t index)
: array_(arr)
, index_(index)
{}
@@ -151,7 +157,6 @@ public:
unsigned int size() const;
IfcUtil::ArgumentType type() const;
// AttributeValue* operator[](unsigned int index) const = 0;
};
class IFC_PARSE_API IfcEntityInstanceData {
@@ -164,6 +169,13 @@ class IFC_PARSE_API IfcEntityInstanceData {
IfcEntityInstanceData(const IfcEntityInstanceData& data);
IfcEntityInstanceData& operator=(IfcEntityInstanceData&& other) {
if (this != &other) {
storage_ = std::move(other.storage_);
}
return *this;
}
AttributeValue get_attribute_value(size_t index) const;
/*
@@ -177,9 +189,7 @@ class IFC_PARSE_API IfcEntityInstanceData {
return storage_.size();
}
// @todo can no longer work because we don't have access to type anymore to lookup derived
std::string toString(bool upper = false) const;
void toString(std::ostream&, bool upper = false) const;
void toString(std::ostream&, bool upper = false, const IfcParse::entity* ent = nullptr) const;
};
#endif
+322
View File
@@ -0,0 +1,322 @@
#include "IfcFile.h"
IfcParse::parse_context::~parse_context() {
for (auto& t : tokens_) {
boost::apply_visitor([](auto& v) {
if constexpr (std::is_same_v<std::decay_t<decltype(v)>, parse_context*>) {
delete v;
}
}, t);
}
}
IfcParse::parse_context& IfcParse::parse_context::push() {
auto* pc = new IfcParse::parse_context;
tokens_.push_back(pc);
return *pc;
}
void IfcParse::parse_context::push(Token t) {
tokens_.push_back(t);
}
void IfcParse::parse_context::push(IfcUtil::IfcBaseClass* inst) {
tokens_.push_back(inst);
}
namespace {
// Define a template to check if a type is in a boost::variant
template<typename Variant, typename T>
struct is_type_in_variant;
// Specialization for boost::variant
template<typename T, typename... Types>
struct is_type_in_variant<boost::variant<Types...>, T>
{
// Recursive template to check if T is one of Types
static constexpr bool value = (std::is_same<T, Types>::value || ...);
};
// Helper variable template (C++14 and beyond)
template<typename Variant, typename T>
constexpr bool is_type_in_variant_v = is_type_in_variant<Variant, T>::value;
IfcUtil::ArgumentType get_element_type(IfcUtil::ArgumentType aggregate) {
switch (aggregate) {
case IfcUtil::Argument_AGGREGATE_OF_INT:
return IfcUtil::Argument_INT;
case IfcUtil::Argument_AGGREGATE_OF_DOUBLE:
return IfcUtil::Argument_DOUBLE;
case IfcUtil::Argument_AGGREGATE_OF_STRING:
return IfcUtil::Argument_STRING;
case IfcUtil::Argument_AGGREGATE_OF_BINARY:
return IfcUtil::Argument_BINARY;
case IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE:
return IfcUtil::Argument_ENTITY_INSTANCE;
case IfcUtil::Argument_AGGREGATE_OF_EMPTY_AGGREGATE:
return IfcUtil::Argument_EMPTY_AGGREGATE;
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT:
return IfcUtil::Argument_AGGREGATE_OF_INT;
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE:
return IfcUtil::Argument_AGGREGATE_OF_DOUBLE;
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE:
return IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE;
default:
return IfcUtil::Argument_UNKNOWN;
}
}
bool can_coerce(IfcUtil::ArgumentType target, IfcUtil::ArgumentType source) {
if (source == IfcUtil::Argument_EMPTY_AGGREGATE) {
return target == IfcUtil::Argument_AGGREGATE_OF_INT ||
target == IfcUtil::Argument_AGGREGATE_OF_DOUBLE ||
target == IfcUtil::Argument_AGGREGATE_OF_STRING ||
target == IfcUtil::Argument_AGGREGATE_OF_BINARY ||
target == IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE ||
target == IfcUtil::Argument_AGGREGATE_OF_EMPTY_AGGREGATE ||
target == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT ||
target == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE ||
target == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE;
} else if (source == IfcUtil::Argument_AGGREGATE_OF_EMPTY_AGGREGATE) {
return target == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT ||
target == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE ||
target == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE;
} else if (source == IfcUtil::Argument_BOOL && target == IfcUtil::Argument_LOGICAL) {
return true;
} else {
// @todo make it configurable to coerce int to double, which is not standard compliant?
auto elt = get_element_type(target);
auto els = get_element_type(source);
if (elt != IfcUtil::Argument_UNKNOWN && els != IfcUtil::Argument_UNKNOWN) {
return can_coerce(elt, els);
}
return false;
}
}
// we need to have a compatibility between (#123, IfcLengthMeasure(123.))
// which are different token kinds
void get_token_type(std::vector<uint8_t>& r, const boost::variant<IfcUtil::IfcBaseClass*,IfcParse::Token, IfcParse::parse_context*>& v) {
r.push_back((uint8_t)v.which());
if (v.which() == 0) {
// pass
} else if (v.which() == 1) {
r.push_back((uint8_t)boost::get<IfcParse::Token>(v).type);
} else if (v.which() == 2) {
// @todo check for empty aggregate
get_token_type(r, boost::get<IfcParse::parse_context*>(v)->tokens_.front());
}
}
bool can_coerce(const std::vector<uint8_t>& target, const std::vector<uint8_t>& source) {
if (target == std::vector<uint8_t>{0, 0} && source == std::vector<uint8_t>{1, IfcParse::Token_IDENTIFIER}) {
return true;
}
if (source == std::vector<uint8_t>{0, 0} && target == std::vector<uint8_t>{1, IfcParse::Token_IDENTIFIER}) {
return true;
}
return source == target;
}
struct InstanceReference {
int v;
operator int() const {
return v;
}
};
template <typename Fn>
void dispatch_token(IfcParse::Token t, IfcParse::declaration* decl, Fn fn) {
if (t.type == IfcParse::Token_BINARY) {
fn(IfcParse::TokenFunc::asBinary(t));
} else if (t.type == IfcParse::Token_BOOL) {
fn(IfcParse::TokenFunc::asBool(t));
} else if (t.type == IfcParse::Token_ENUMERATION) {
if (decl->as_enumeration_type()) {
fn(EnumerationReference(decl->as_enumeration_type(), decl->as_enumeration_type()->lookup_enum_offset(IfcParse::TokenFunc::asStringRef(t))));
}
} else if (t.type == IfcParse::Token_FLOAT) {
fn(IfcParse::TokenFunc::asFloat(t));
} else if (t.type == IfcParse::Token_IDENTIFIER) {
fn(InstanceReference{ IfcParse::TokenFunc::asIdentifier(t) });
} else if (t.type == IfcParse::Token_INT) {
fn(IfcParse::TokenFunc::asInt(t));
} else if (t.type == IfcParse::Token_STRING) {
fn(IfcParse::TokenFunc::asStringRef(t));
}
}
template <typename Fn>
void construct_(IfcParse::parse_context& p, Fn fn) {
if (p.tokens_.empty()) {
// @todo based on type create appropate empty aggregate
return;
}
decltype(p.tokens_) p_tokens_filtered;
std::vector<uint8_t> first_type;
get_token_type(first_type, p.tokens_.front());
std::copy_if(
p.tokens_.begin(),
p.tokens_.end(),
std::back_inserter(p_tokens_filtered),
[first_type](auto& x) {
std::vector<uint8_t> nth_type;
get_token_type(nth_type, x);
return can_coerce(first_type, nth_type);
}
);
if (p.tokens_.size() != p_tokens_filtered.size()) {
// warning
}
typedef boost::variant<
Blank,
std::vector<int>,
std::vector<double>,
std::vector<std::string>,
std::vector<boost::dynamic_bitset<>>,
std::vector<IfcParse::reference_or_simple_type>,
std::vector<std::vector<int>>,
std::vector<std::vector<double>>,
std::vector<std::vector<IfcParse::reference_or_simple_type>>
> possible_aggregation_types_t;
possible_aggregation_types_t aggregate_storage;
for (auto& t : p_tokens_filtered) {
boost::apply_visitor([&aggregate_storage](auto& v) {
if constexpr (std::is_same_v<std::decay_t<decltype(v)>, IfcParse::Token>) {
// @todo get aggregate of enumeration
dispatch_token(v, nullptr, [&aggregate_storage](auto v) {
if constexpr (std::is_same_v<decltype(v), InstanceReference>) {
if (aggregate_storage.which() == 0) {
aggregate_storage = std::vector<IfcParse::reference_or_simple_type>{ v };
} else {
boost::get< std::vector<IfcParse::reference_or_simple_type>>(aggregate_storage).push_back(v);
}
} else if constexpr (is_type_in_variant_v<possible_aggregation_types_t, std::vector<std::decay_t<decltype(v)>>>) {
if (aggregate_storage.which() == 0) {
aggregate_storage = std::vector<std::decay_t<decltype(v)>>{ v };
} else {
boost::get< std::vector<std::decay_t<decltype(v)>>>(aggregate_storage).push_back(v);
}
}
});
} else if constexpr (std::is_same_v<std::decay_t<decltype(v)>, IfcParse::parse_context*>) {
/*construct_(*v, [&aggregate_storage](auto& v) {
if (aggregate_storage.which() == 0) {
aggregate_storage = std::vector<std::decay_t<decltype(v)>>{ v };
} else {
boost::get<std::vector<std::decay_t<decltype(v)>>>(aggregate_storage).push_back(v);
}
});*/
// Too deeply nested list
} else {
if (aggregate_storage.which() == 0) {
aggregate_storage = std::vector<IfcParse::reference_or_simple_type>{ v };
} else {
boost::get<std::vector<IfcParse::reference_or_simple_type>>(aggregate_storage).push_back(v);
}
}
}, t);
}
boost::apply_visitor(fn, aggregate_storage);
}
}
IfcEntityInstanceData IfcParse::parse_context::construct(int name, unresolved_references& references_to_resolve, const IfcParse::declaration* decl) {
std::vector<const IfcParse::parameter_type*> parameter_types;
if (decl && decl->as_type_declaration()) {
parameter_types = { decl->as_type_declaration()->declared_type() };
} else if (decl && decl->as_entity()) {
auto entity_attrs = decl->as_entity()->all_attributes();
std::transform(
entity_attrs.begin(),
entity_attrs.end(),
std::back_inserter(parameter_types),
[](auto* attr) {
return attr->type_of_attribute();
}
);
}
std::vector<IfcUtil::ArgumentType> attr_types;
std::transform(
parameter_types.begin(),
parameter_types.end(),
std::back_inserter(attr_types),
IfcUtil::from_parameter_type
);
if (decl && (tokens_.size() != attr_types.size())) {
// warning
}
if (tokens_.size() == 0) {
return IfcEntityInstanceData(storage_t(0));
}
storage_t storage(decl
? (std::min)(attr_types.size(), tokens_.size())
: tokens_.size()
);
auto it = tokens_.begin();
auto jt = attr_types.begin();
auto kt = parameter_types.begin();
for (; it != tokens_.end() && (!decl || jt != attr_types.end()); ++it) {
auto& token = *it;
// @todo coerce to expected type, e.g empty -> std::vector<int>, bool -> logical
// auto& attr_type = *jt;
const IfcParse::parameter_type* param_type = nullptr;
if (decl) {
param_type = *kt;
}
auto index = (uint8_t) std::distance(tokens_.begin(), it);
boost::apply_visitor([this, &storage, name, &references_to_resolve, index, it, param_type](auto& v) {
if constexpr (std::is_same_v<std::decay_t<decltype(v)>, IfcParse::Token>) {
dispatch_token(v, param_type && param_type->as_named_type() ? param_type->as_named_type()->declared_type() : nullptr, [this, &storage, name, &references_to_resolve, index](auto v) {
if constexpr (std::is_same_v<std::decay_t<decltype(v)>, InstanceReference>) {
references_to_resolve.push_back(std::make_pair(
// @todo previously this was storage but apparently the
// pointer is not constant with the moving and temporary nature
// maybe it ought to be and in that case a pointer is more direct
MutableAttributeValue{ name, index },
unresolved_references::value_type::second_type{v}
));
} else {
storage.set(index, v);
}
});
} else if constexpr (std::is_same_v<std::decay_t<decltype(v)>, IfcParse::parse_context*>) {
construct_(*v, [this, &storage, name, &references_to_resolve, index](auto& v) {
if constexpr (std::is_same_v<std::decay_t<decltype(v)>, std::vector<reference_or_simple_type>>) {
references_to_resolve.push_back({ {name, index }, v });
} else if constexpr (std::is_same_v<std::decay_t<decltype(v)>, std::vector<std::vector<reference_or_simple_type>>>) {
references_to_resolve.push_back({ {name, index }, v });
} else {
storage.set(index, v);
}
});
} else {
storage.set(index, v);
}
}, token);
if (decl) {
++jt, ++kt;
}
}
return IfcEntityInstanceData(std::move(storage));
}
+20 -58
View File
@@ -65,79 +65,41 @@ class IFC_PARSE_API file_open_status {
}
};
typedef boost::variant<int, IfcUtil::IfcBaseClass*> reference_or_simple_type;
typedef std::list<std::pair<MutableAttributeValue, boost::variant<reference_or_simple_type, std::vector<reference_or_simple_type>, std::vector<std::vector<reference_or_simple_type>>>>> unresolved_references;
struct parse_context {
boost::variant<
Blank,
storage_t, // IFCWALL(x)
std::vector<Token>, // IFCCARTESIANPOINT((x, y, z))
std::vector<IfcUtil::IfcBaseClass*>, // IFCCARTESIANPOINT((IFCTEXT(), IFCTEXT()))
std::list<parse_context> // IFCCARTESIANPOINTLIST3D(((x, y, z), (q, r, s)))
> tokens;
std::list<
boost::variant<
IfcUtil::IfcBaseClass*,
Token,
parse_context*
>> tokens_;
parse_context() {};
~parse_context();
parse_context(const parse_context&) = delete;
parse_context& operator=(const parse_context&) = delete;
parse_context()
: tokens(Blank{})
{}
parse_context(parse_context&&) = default;
parse_context& operator=(parse_context&&) = default;
parse_context(storage_t&& instance_attribute_storage)
: tokens(std::move(instance_attribute_storage))
{}
parse_context& push();
parse_context& push() {
if (tokens.which() == 0) {
// tokens = std::vector<Token>{};
throw std::runtime_error("d");
} else if (tokens.which() == 1) {
throw std::runtime_error("e");
} else if (tokens.which() == 2) {
throw std::runtime_error("e");
} else if (tokens.which() == 3) {
if (boost::get<std::vector<Token>>(tokens).size() == 0) {
tokens = std::list<parse_context>{};
return push();
} else {
throw std::runtime_error("b");
}
} else if (tokens.which() == 4) {
boost::get<std::list<parse_context>>(tokens).emplace_back();
return boost::get<std::list<parse_context>>(tokens).back();
}
}
void push(Token t);
void push(Token t) {
if (tokens.which() == 1) {
boost::get<std::vector<Token>>(tokens).push_back(t);
} else if (tokens.which() == 3) {
boost::get<std::list<parse_context>>(tokens).back().push(t);
} else {
throw std::runtime_error("a");
}
}
void push(IfcUtil::IfcBaseClass* inst);
void push(IfcUtil::IfcBaseClass* inst) {
if (tokens.which() == 2) {
boost::get<std::vector<IfcUtil::IfcBaseClass*>>(tokens).push_back(inst);
} else if (tokens.which() == 3) {
boost::get<std::list<parse_context>>(tokens).back().push(inst);
} else {
throw std::runtime_error("a");
}
}
void pop() {
}
storage_t&& data() {
return std::move(boost::get<storage_t>(tokens));
}
IfcEntityInstanceData construct(int name, unresolved_references& references_to_resolve, const IfcParse::declaration* decl);
};
/// This class provides several static convenience functions and variables
/// and provide access to the entities in an IFC file
class IFC_PARSE_API IfcFile {
public:
unresolved_references references_to_resolve;
typedef std::map<const IfcParse::declaration*, aggregate_of_instance::ptr> entities_by_type_t;
typedef boost::unordered_map<unsigned int, IfcUtil::IfcBaseClass*> entity_by_id_t;
typedef boost::unordered_map<uint32_t, IfcUtil::IfcBaseClass*> entity_by_iden_t;
+9 -3
View File
@@ -70,7 +70,9 @@ void plain_text_message(T& out, const boost::optional<const IfcUtil::IfcBaseClas
}
out << message.c_str() << std::endl;
if (instance) {
std::string instance_string = instance->data().toString();
std::ostringstream oss;
instance->as<IfcUtil::IfcBaseClass>()->toString(oss);
auto instance_string = oss.str();
if (instance_string.size() > 259) {
instance_string = instance_string.substr(0, 256) + "...";
}
@@ -98,11 +100,15 @@ void json_message(T& out, const boost::optional<const IfcUtil::IfcBaseClass*>& c
property_tree.put(level_string, severity_strings<typename T::char_type>::value[type]);
if (current_product) {
property_tree.put(product_string, string_as<typename T::char_type>((**current_product).data().toString()));
std::ostringstream oss;
(*current_product)->toString(oss);
property_tree.put(product_string, string_as<typename T::char_type>(oss.str()));
}
property_tree.put(message_string, string_as<typename T::char_type>(message));
if (instance) {
property_tree.put(instance_string, string_as<typename T::char_type>(instance->data().toString()));
std::ostringstream oss;
instance->as<IfcUtil::IfcBaseClass>()->toString(oss);
property_tree.put(instance_string, string_as<typename T::char_type>(oss.str()));
}
property_tree.put(time_string, string_as<typename T::char_type>(get_time()));
+137 -188
View File
@@ -366,10 +366,14 @@ Token IfcSpfLexer::Next() {
decoder_->skip();
}
}
Token t;
if (len != 0) {
return GeneralTokenPtr(this, pos, stream->Tell());
t = GeneralTokenPtr(this, pos, stream->Tell());
} else {
t = NoneTokenPtr();
}
return NoneTokenPtr();
// std::wcout << "token: " << pos << " " << TokenFunc::asStringRef(t).c_str() << std::endl;
return t;
}
bool IfcSpfStream::is_eof_at(unsigned int local_ptr) {
@@ -685,6 +689,10 @@ std::string TokenFunc::toString(const Token& token) {
void IfcParse::IfcFile::load(unsigned entity_instance_name, const IfcParse::entity* entity, parse_context& context, int attribute_index) {
Token next = tokens->Next();
if (TokenFunc::isOperator(next, '(')) {
next = tokens->Next();
}
/*
std::vector<Argument*>* vector = 0;
vector_or_array<Argument*> filler(attributes, num_attributes);
@@ -711,7 +719,7 @@ void IfcParse::IfcFile::load(unsigned entity_instance_name, const IfcParse::enti
while ((next.startPos != 0U) || (next.lexer != nullptr)) {
if (TokenFunc::isOperator(next, ',')) {
if (attribute_index == 0) {
if (attribute_index == -1) {
attribute_index_within_data += 1;
}
} else if (TokenFunc::isOperator(next, ')')) {
@@ -722,17 +730,17 @@ void IfcParse::IfcFile::load(unsigned entity_instance_name, const IfcParse::enti
} else {
return_value++;
if (TokenFunc::isIdentifier(next)) {
// register_inverse(entity_instance_name, entity, next, attribute_index == -1 ? attribute_index_within_data : attribute_index);
register_inverse(entity_instance_name, entity, next, attribute_index == -1 ? attribute_index_within_data : attribute_index);
}
if (TokenFunc::isKeyword(next)) {
try {
parse_context ps(storage_t(1));
parse_context ps;
load(0, nullptr, ps, -1);
IfcParse::schema_definition* schema;
auto* simple_type_instance = schema->instantiate(TokenFunc::asStringRef(next), IfcEntityInstanceData(ps.data()));
auto* simple_type_instance = schema_->instantiate(TokenFunc::asStringRef(next), ps.construct(-1, references_to_resolve, schema_->declaration_by_name(TokenFunc::asStringRef(next))));
//@todo decide addEntity(((IfcUtil::IfcBaseClass*)*entity));
context.push(simple_type_instance);
simple_type_instance->file_ = this;
} catch (IfcException& e) {
Logger::Message(Logger::LOG_ERROR, e.what());
// #4070 We didn't actually capture an aggregate entry, undo length increment.
@@ -744,103 +752,24 @@ void IfcParse::IfcFile::load(unsigned entity_instance_name, const IfcParse::enti
}
next = tokens->Next();
}
/*
if (vector != nullptr) {
// Obviously don't try and create a 0-length array.
if ((num_attributes != 0U) || !vector->empty()) {
// @todo figure out whether all this logic is still necessary, since we know the
// expected amount of attributes and shouldn't be able to access more than allowed
// by the schema.
attributes = new Argument* [(std::max)(num_attributes, vector->size())] { nullptr };
// @todo this appears unnecessary, we increment this in the loop already,
// which is more accurate as the filler can't go above it's size in case
// it uses the pre-allocated c-array.
// -> return_value = vector->size();
for (size_t i = 0; i < vector->size(); ++i) {
attributes[i] = vector->at(i);
}
}
if ((vector != &internal_attribute_vector_) && (vector != &internal_attribute_vector_simple_type_)) {
delete vector;
}
}
return return_value;
*/
}
// templated helper function for reading arguments into a list
template <typename T>
std::vector<T> read_aggregate_as_vector(const std::vector<Token>& tokens) {
std::vector<T> return_value;
return_value.reserve(tokens.size());
for (size_t i = 0; i < tokens.size(); ++i) {
return_value.push_back(tokens[i]);
}
return return_value;
}
template <typename T>
std::vector<std::vector<T>> read_aggregate_of_aggregate_as_vector2(const std::vector<parse_context>& tokens) {
std::vector<std::vector<T>> return_value;
return_value.reserve(tokens.size());
for (size_t i = 0; i < tokens.size(); ++i) {
return_value.push_back(read_aggregate_as_vector<T>(boost::get< std::vector<Token>>(tokens[i].tokens)));
}
return return_value;
}
/*
IfcUtil::ArgumentType TokenArgument::type() const {
if (TokenFunc::isInt(token)) {
return IfcUtil::Argument_INT;
}
if (TokenFunc::isBool(token)) {
return IfcUtil::Argument_BOOL;
}
if (TokenFunc::isLogical(token)) {
return IfcUtil::Argument_LOGICAL;
}
if (TokenFunc::isFloat(token)) {
return IfcUtil::Argument_DOUBLE;
}
if (TokenFunc::isString(token)) {
return IfcUtil::Argument_STRING;
}
if (TokenFunc::isEnumeration(token)) {
return IfcUtil::Argument_ENUMERATION;
}
if (TokenFunc::isIdentifier(token)) {
return IfcUtil::Argument_ENTITY_INSTANCE;
}
if (TokenFunc::isBinary(token)) {
return IfcUtil::Argument_BINARY;
}
if (TokenFunc::isOperator(token, '$')) {
return IfcUtil::Argument_NULL;
}
if (TokenFunc::isOperator(token, '*')) {
return IfcUtil::Argument_DERIVED;
}
return IfcUtil::Argument_UNKNOWN;
}
*/
//
// Reads an Entity from the list of Tokens at the specified offset in the file
//
IfcEntityInstanceData&& IfcParse::read(unsigned int i, IfcFile* f) {
IfcEntityInstanceData IfcParse::read(unsigned int i, IfcFile* f) {
Token datatype = f->tokens->Next();
if (!TokenFunc::isKeyword(datatype)) {
throw IfcException("Unexpected token while parsing entity");
}
const IfcParse::declaration* ty = f->schema()->declaration_by_name(TokenFunc::asStringRef(datatype));
parse_context pc(storage_t((uint8_t) ty->as_entity()->all_attributes().size()));
parse_context pc;
f->load(i, ty->as_entity(), pc, -1);
return IfcEntityInstanceData(pc.data());
return IfcEntityInstanceData(pc.construct(i, f->references_to_resolve, ty));
/*std::ostringstream oss;
d.toString(oss);
auto osss = oss.str();
std::wcout << osss.c_str() << std::endl;*/
}
void IfcParse::IfcFile::try_read_semicolon() {
@@ -900,7 +829,7 @@ namespace {
StringBuilderVisitor(const StringBuilderVisitor&); //N/A
StringBuilderVisitor& operator=(const StringBuilderVisitor&); //N/A
std::ostringstream& data_;
std::ostream& data_;
template <typename T>
void serialize(const std::vector<T>& i) {
data_ << "(";
@@ -961,7 +890,7 @@ namespace {
bool upper_;
public:
StringBuilderVisitor(std::ostringstream& stream, bool upper = false)
StringBuilderVisitor(std::ostream& stream, bool upper = false)
: data_(stream),
upper_(upper) {}
void operator()(const Blank& /*i*/) { data_ << "$"; }
@@ -1024,7 +953,6 @@ namespace {
}
void operator()(const empty_aggregate_t&) const { data_ << "()"; }
void operator()(const empty_aggregate_of_aggregate_t&) const { data_ << "()"; }
operator std::string() { return data_.str(); }
};
template <>
@@ -1094,8 +1022,7 @@ namespace {
// Returns a string representation of the entity
// Note that this initializes the entity if it is not initialized
//
std::string IfcEntityInstanceData::toString(bool upper) const {
std::ostringstream ss;
void IfcEntityInstanceData::toString(std::ostream& ss, bool upper, const entity* decl) const {
ss.imbue(std::locale::classic());
/*
@@ -1120,23 +1047,17 @@ std::string IfcEntityInstanceData::toString(bool upper) const {
if (i != 0) {
ss << ",";
}
/*
if (storage_.has<Blank>(i)) {
// @todo
if (type_->as_entity() != nullptr && type_->as_entity()->derived()[i]) {
if (decl != nullptr && decl->derived()[i]) {
ss << "*";
} else {
ss << "$";
// }
}
} else {
storage_.apply_visitor(vis, i);
}
*/
storage_.apply_visitor(vis, i);
}
ss << ")";
return ss.str();
}
unsigned IfcUtil::IfcBaseEntity::set_id(const boost::optional<unsigned>& i) {
@@ -1145,39 +1066,6 @@ unsigned IfcUtil::IfcBaseEntity::set_id(const boost::optional<unsigned>& i) {
}
return id_ = file_->FreshId();
}
/*
void IfcEntityInstanceData::load() const {
Argument** tmp_data = nullptr;
if (file->parsing_complete()) {
// only when parsing is fully complete we need to seek to the instance, otherwise
// we know the token cursor is currently at the keyword token
file->seek_to(*this);
} else {
// Apparently the load() function assumes one token later after the opening parenthesis
file->tokens->Next();
}
// type_ is 0 for header entities which have their size predetermined in code
// in that we have attributes_ pre-constructed to the correct size in the constructor
// in the other case load() will use a vector internally to grow to the size found in the file
size_t n = file->load(id(), type_ != nullptr ? type_->as_entity() : nullptr, type_ != nullptr ? tmp_data : attributes_, getArgumentCount());
if (n != getArgumentCount()) {
Logger::Error("Wrong number of attributes on instance with id #" + std::to_string(id_) +
" at offset " + std::to_string(this->offset_in_file()) +
" expected " + std::to_string(getArgumentCount()) +
" got " + std::to_string(n));
}
file->try_read_semicolon();
// @todo does this need to be atomic somehow?
if (tmp_data != nullptr) {
attributes_ = tmp_data;
}
}
*/
namespace {
// @todo remove redundancy with python wrapper code (which is not identical due to
@@ -1202,24 +1090,6 @@ IfcUtil::ArgumentType get_argument_type(const IfcParse::declaration* decl, size_
}
} // namespace
/*
IfcEntityInstanceData::IfcEntityInstanceData(const IfcEntityInstanceData& data) {
file = 0;
type_ = data.type_;
id_ = 0;
const size_t count = data.getArgumentCount();
// In order not to have the instance read from file
attributes_ = new Argument*[count];
for (unsigned int i = 0; i < count; ++i) {
attributes_[i] = 0;
this->setArgument(i, data.get_attribute_value(i), get_argument_type(data.type(), i), true);
}
}
*/
class unregister_inverse_visitor {
private:
IfcFile& file_;
@@ -1265,16 +1135,12 @@ class add_to_instance_list_visitor {
class apply_individual_instance_visitor {
private:
AttributeValue attribute_;
boost::optional<AttributeValue> attribute_;
IfcEntityInstanceData* data_;
int attribute_index_;
template <typename T>
void apply_attribute_(T& t, const AttributeValue& attr, int index) const {
if (!attr) {
return;
}
if (attr.type() == IfcUtil::Argument_ENTITY_INSTANCE) {
IfcUtil::IfcBaseClass* inst = attr;
t(inst, index);
@@ -1306,7 +1172,7 @@ class apply_individual_instance_visitor {
template <typename T>
void apply(T& t) const {
if (attribute_) {
apply_attribute_(t, attribute_, attribute_index_);
apply_attribute_(t, *attribute_, attribute_index_);
} else {
for (size_t i = 0; i < data_->size(); ++i) {
auto attr = data_->get_attribute_value(i);
@@ -1554,7 +1420,7 @@ void IfcFile::initialize_(IfcParse::IfcSpfStream* s) {
stream = 0;
schema_ = 0;
setDefaultHeaderValues();
// setDefaultHeaderValues();
stream = s;
if (!stream->valid) {
@@ -1625,11 +1491,11 @@ void IfcFile::initialize_(IfcParse::IfcSpfStream* s) {
goto advance;
}
// @todo implement attribute_size() accessor
parse_context ps(storage_t(entity_type->as_entity()->all_attributes().size()));
parse_context ps;
load(current_id, entity_type->as_entity(), ps, -1);
IfcParse::schema_definition* schema;
instance = schema->instantiate(entity_type->name(), IfcEntityInstanceData(ps.data()));
instance = schema_->instantiate(entity_type->name(), ps.construct(current_id, references_to_resolve, entity_type));
instance->file_ = this;
instance->id_ = current_id;
/// @todo Printing to stdout in a library class feels weird. Maybe move the progress prints to the client code?
// Update the status after every 1000 instances parsed
@@ -1722,6 +1588,58 @@ void IfcFile::initialize_(IfcParse::IfcSpfStream* s) {
Logger::Status("\rDone scanning file ");
for (auto& p : references_to_resolve) {
boost::apply_visitor([this, &p](auto& v) {
if constexpr (std::is_same_v<std::decay_t<decltype(v)>, reference_or_simple_type>) {
byid_[p.first.name_]->data().storage_.set(p.first.index_, boost::apply_visitor([this](auto inst) {
IfcUtil::IfcBaseClass* ptr;
if constexpr (std::is_same_v<decltype(inst), int>) {
ptr = this->instance_by_id(inst);
} else {
ptr = inst;
}
return ptr;
}, v));
} else if constexpr (std::is_same_v<std::decay_t<decltype(v)>, std::vector<reference_or_simple_type>>) {
aggregate_of_instance::ptr instances(new aggregate_of_instance);
for (auto& p : v) {
instances->push(boost::apply_visitor([this](auto inst) {
IfcUtil::IfcBaseClass* ptr;
if constexpr (std::is_same_v<decltype(inst), int>) {
ptr = this->instance_by_id(inst);
} else {
ptr = inst;
}
return ptr;
}, p));
}
byid_[p.first.name_]->data().storage_.set(p.first.index_, instances);
} else if constexpr (std::is_same_v<std::decay_t<decltype(v)>, std::vector<std::vector<reference_or_simple_type>>>) {
aggregate_of_aggregate_of_instance::ptr instances(new aggregate_of_aggregate_of_instance);
for (auto& ps : v) {
std::vector<IfcUtil::IfcBaseClass*> inner;
for (auto& p : ps) {
inner.push_back(boost::apply_visitor([this](auto inst) {
IfcUtil::IfcBaseClass* ptr;
if constexpr (std::is_same_v<decltype(inst), int>) {
ptr = this->instance_by_id(inst);
} else {
ptr = inst;
}
return ptr;
}, p));
}
instances->push(inner);
}
byid_[p.first.name_]->data().storage_.set(p.first.index_, instances);
} else {
static_assert(false, "Inconsistent type");
}
}, p.second);
}
references_to_resolve.clear();
return;
}
@@ -2414,7 +2332,8 @@ std::ostream& operator<<(std::ostream& out, const IfcParse::IfcFile& file) {
for (vector_t::const_iterator it = sorted.begin(); it != sorted.end(); ++it) {
const IfcUtil::IfcBaseClass* e = it->second;
if (e->declaration().as_entity() != nullptr) {
out << e->data().toString(true) << ";" << std::endl;
e->toString(out, true);
out << ";" << std::endl;
}
}
@@ -2646,6 +2565,15 @@ void IfcUtil::IfcBaseClass::unset_attribute_value(size_t index) {
data_.storage_.set(index, Blank{});
}
void IfcUtil::IfcBaseClass::toString(std::ostream& out, bool upper) const
{
auto ent = declaration().as_entity();
if (ent) {
out << "#" << as<IfcUtil::IfcBaseEntity>()->id();
}
data().toString(out, upper, ent);
}
IfcEntityInstanceData::IfcEntityInstanceData(const IfcEntityInstanceData& data)
: storage_(data.storage_.size() )
{
@@ -2656,21 +2584,42 @@ IfcEntityInstanceData::IfcEntityInstanceData(const IfcEntityInstanceData& data)
}
}
/*
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_value<int>(int index, const int& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_value<bool>(int index, const bool& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_value<boost::logic::tribool>(int index, const boost::logic::tribool& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_value<double>(int index, const double& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_value<std::string>(int index, const std::string& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_value<boost::dynamic_bitset<>>(int index, const boost::dynamic_bitset<>& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_value<IfcWrite::IfcWriteArgument::EnumerationReference>(int index, const IfcWrite::IfcWriteArgument::EnumerationReference& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_value<IfcUtil::IfcBaseClass*>(int index, IfcUtil::IfcBaseClass* const& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_value<std::vector<int>>(int index, const std::vector<int>& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_value<std::vector<double>>(int index, const std::vector<double>& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_value<std::vector<std::string>>(int index, const std::vector<std::string>& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_value<std::vector<boost::dynamic_bitset<>>>(int index, const std::vector<boost::dynamic_bitset<>>& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_value<aggregate_of_instance::ptr>(int index, const aggregate_of_instance::ptr& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_value<std::vector<std::vector<int>>>(int index, const std::vector<std::vector<int>>& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_value<std::vector<std::vector<double>>>(int index, const std::vector<std::vector<double>>& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_value<aggregate_of_aggregate_of_instance::ptr>(int index, const aggregate_of_aggregate_of_instance::ptr& value);
*/
AttributeValue IfcEntityInstanceData::get_attribute_value(size_t index) const
{
return { &storage_, (uint8_t) index };
}
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<int>(size_t index, const int& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<bool>(size_t index, const bool& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<boost::logic::tribool>(size_t index, const boost::logic::tribool& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<double>(size_t index, const double& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<std::string>(size_t index, const std::string& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<boost::dynamic_bitset<>>(size_t index, const boost::dynamic_bitset<>& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<EnumerationReference>(size_t index, const EnumerationReference& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<IfcUtil::IfcBaseClass*>(size_t index, IfcUtil::IfcBaseClass* const& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<std::vector<int>>(size_t index, const std::vector<int>& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<std::vector<double>>(size_t index, const std::vector<double>& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<std::vector<std::string>>(size_t index, const std::vector<std::string>& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<std::vector<boost::dynamic_bitset<>>>(size_t index, const std::vector<boost::dynamic_bitset<>>& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<aggregate_of_instance::ptr>(size_t index, const aggregate_of_instance::ptr& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<std::vector<std::vector<int>>>(size_t index, const std::vector<std::vector<int>>& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<std::vector<std::vector<double>>>(size_t index, const std::vector<std::vector<double>>& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<aggregate_of_aggregate_of_instance::ptr>(size_t index, const aggregate_of_aggregate_of_instance::ptr& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<int>(const std::string& name, const int& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<bool>(const std::string& name, const bool& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<boost::logic::tribool>(const std::string& name, const boost::logic::tribool& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<double>(const std::string& name, const double& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<std::string>(const std::string& name, const std::string& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<boost::dynamic_bitset<>>(const std::string& name, const boost::dynamic_bitset<>& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<EnumerationReference>(const std::string& name, const EnumerationReference& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<IfcUtil::IfcBaseClass*>(const std::string& name, IfcUtil::IfcBaseClass* const& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<std::vector<int>>(const std::string& name, const std::vector<int>& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<std::vector<double>>(const std::string& name, const std::vector<double>& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<std::vector<std::string>>(const std::string& name, const std::vector<std::string>& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<std::vector<boost::dynamic_bitset<>>>(const std::string& name, const std::vector<boost::dynamic_bitset<>>& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<aggregate_of_instance::ptr>(const std::string& name, const aggregate_of_instance::ptr& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<std::vector<std::vector<int>>>(const std::string& name, const std::vector<std::vector<int>>& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<std::vector<std::vector<double>>>(const std::string& name, const std::vector<std::vector<double>>& value);
template void IFC_PARSE_API IfcUtil::IfcBaseClass::set_attribute_value<aggregate_of_aggregate_of_instance::ptr>(const std::string& name, const aggregate_of_aggregate_of_instance::ptr& value);
+1 -1
View File
@@ -164,7 +164,7 @@ class IFC_PARSE_API IfcSpfLexer {
void TokenString(unsigned int offset, std::string& result);
};
IFC_PARSE_API IfcEntityInstanceData&& read(unsigned int index, IfcFile* file);
IFC_PARSE_API IfcEntityInstanceData read(unsigned int index, IfcFile* file);
IFC_PARSE_API aggregate_of_instance::ptr traverse(IfcUtil::IfcBaseClass* instance, int max_level = -1);
+22 -11
View File
@@ -36,18 +36,26 @@ static const char* const DATA = "DATA";
using namespace IfcParse;
HeaderEntity::HeaderEntity(const char* const datatype, size_t size, IfcFile* file)
: IfcEntityInstanceData(file, size),
datatype_(datatype),
size_(size) {
if (file != nullptr) {
offset_in_file_ = file->stream->Tell();
load();
namespace {
IfcEntityInstanceData read_from_file(IfcFile* f, size_t s) {
parse_context pc;
f->load(-1, nullptr, pc, -1);
return pc.construct(-1, f->references_to_resolve, nullptr);
/*std::ostringstream oss;
ent.toString(oss);
auto osss = oss.str();
std::wcout << osss.c_str() << std::endl;*/
// return ent;
}
}
HeaderEntity::HeaderEntity(const char* const datatype, size_t size, IfcFile* file)
: data_(file ? read_from_file(file, size) : IfcEntityInstanceData(storage_t(size)))
, datatype_(datatype)
, file_(file)
{}
HeaderEntity::~HeaderEntity() {
clearArguments();
}
void IfcSpfHeader::readSemicolon() {
@@ -89,18 +97,21 @@ void IfcSpfHeader::read() {
readTerminal(FILE_DESCRIPTION, NONE);
delete file_description_;
// readParen();
file_description_ = new FileDescription(file_);
// readSemicolon();
readSemicolon();
readTerminal(FILE_NAME, NONE);
delete file_name_;
// readParen();
file_name_ = new FileName(file_);
// readSemicolon();
readSemicolon();
readTerminal(FILE_SCHEMA, NONE);
delete file_schema_;
// readParen();
file_schema_ = new FileSchema(file_);
// readSemicolon();
readSemicolon();
}
bool IfcSpfHeader::tryRead() {
+14 -9
View File
@@ -21,6 +21,7 @@
#define IFCSPFHEADER_H
#include "ifc_parse_api.h"
#include "IfcEntityInstanceData.h"
namespace IfcParse {
class IfcFile;
@@ -28,8 +29,8 @@ namespace IfcParse {
class IFC_PARSE_API HeaderEntity {
private:
const char* const datatype_;
size_t size_;
IfcFile* file_;
HeaderEntity(const HeaderEntity&); //N/A
HeaderEntity& operator=(const HeaderEntity&); //N/A
protected:
@@ -48,12 +49,13 @@ class IFC_PARSE_API HeaderEntity {
public:
virtual size_t getArgumentCount() const {
return size_;
return data_.size();
}
std::string toString(bool upper = false) const {
std::stringstream stream;
stream << datatype_ << data_.toString(upper);
stream << datatype_;
data_.toString(stream, upper);
return stream.str();
}
};
@@ -115,14 +117,17 @@ class IFC_PARSE_API IfcSpfHeader {
void readTerminal(const std::string& term, Trail trail);
public:
explicit IfcSpfHeader(IfcParse::IfcFile* file = 0)
explicit IfcSpfHeader(IfcParse::IfcFile* file = nullptr)
: file_(file),
file_description_(0),
file_name_(0),
file_schema_(0) {
file_description_ = new FileDescription(file_);
file_name_ = new FileName(file_);
file_schema_ = new FileSchema(file_);
file_schema_(0)
{
if (file == nullptr) {
file_description_ = new FileDescription(file_);
file_name_ = new FileName(file_);
file_schema_ = new FileSchema(file_);
}
}
~IfcSpfHeader() {
+14
View File
@@ -56,6 +56,7 @@
#include "IfcBaseClass.h"
#include "IfcException.h"
#include "utils.h"
#include "IfcFile.h"
#include <algorithm>
#include <boost/algorithm/string/replace.hpp>
@@ -207,6 +208,19 @@ Argument* IfcUtil::IfcBaseEntity::get(const std::string& name) const {
}
*/
AttributeValue IfcUtil::IfcBaseEntity::get(const std::string& name) const
{
auto attrs = declaration().as_entity()->all_attributes();
auto iter = attrs.begin();
size_t idx = 0;
for (; iter != attrs.end(); ++iter, ++idx) {
if ((*iter)->name() == name) {
return data().get_attribute_value(idx);
}
}
throw IfcParse::IfcException(name + " not found on " + declaration().name());
}
aggregate_of_instance::ptr IfcUtil::IfcBaseEntity::get_inverse(const std::string& name) const {
const std::vector<const IfcParse::inverse_attribute*> attrs = declaration().as_entity()->all_inverse_attributes();
std::vector<const IfcParse::inverse_attribute*>::const_iterator iter = attrs.begin();
+81 -55
View File
@@ -27,8 +27,35 @@
#include <boost/algorithm/string.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/any.hpp>
#include <libxml/parser.h>
namespace {
// Base case: when there are no more types left to check.
template <typename Fn>
void visit_any_impl(Fn& fn, const boost::any& a) {
}
// Recursive case: Check the first type in the pack.
template <typename Fn, typename T, typename... Types>
void visit_any_impl(Fn& fn, const boost::any& a) {
if (a.type() == typeid(T)) {
Fn(boost::any_cast<T>(a));
} else {
visit_any_impl<Types...>(a);
}
}
// Helper to prepend a type to a tuple
template <typename Fn, typename U>
void visit_any(Fn fn, const boost::any& a);
template <typename Fn, typename... Types>
void visit_any(Fn fn, const boost::any & a) {
visit_any_impl<Fn, Types...>(fn, a);
};
}
// For debug printing on release builds
// #undef NDEBUG
@@ -71,7 +98,8 @@ class stack_node {
node_header_entry
};
std::vector<Argument*> aggregate_elements;
// to be coerced into the correct type later on
std::vector<boost::any> aggregate_elements;
protected:
node_type type_;
@@ -199,13 +227,12 @@ std::vector<T> split(const std::string& value) {
return r;
}
Argument* parse_attribute_value(const IfcParse::parameter_type* ty, const std::string& value) {
auto* v = new IfcWrite::IfcWriteArgument();
boost::any parse_attribute_value(const IfcParse::parameter_type* ty, const std::string& value) {
boost::any any;
auto cpp_type = IfcUtil::from_parameter_type(ty);
if (cpp_type == IfcUtil::Argument_STRING) {
v->set(value);
any = value;
} else if (cpp_type == IfcUtil::Argument_ENUMERATION) {
const auto* enum_type = ty->as_named_type()->declared_type()->as_enumeration_type();
@@ -214,28 +241,24 @@ Argument* parse_attribute_value(const IfcParse::parameter_type* ty, const std::s
enum_type->enumeration_items().end(),
boost::to_upper_copy(value));
if (iter != enum_type->enumeration_items().end()) {
v->set(IfcWrite::IfcWriteArgument::EnumerationReference(iter - enum_type->enumeration_items().begin(), iter->c_str()));
}
any = EnumerationReference(enum_type, std::distance(enum_type->enumeration_items().begin(), iter));
} else if (cpp_type == IfcUtil::Argument_INT) {
v->set(boost::lexical_cast<int>(value));
any = boost::lexical_cast<int>(value);
} else if (cpp_type == IfcUtil::Argument_DOUBLE) {
v->set(boost::lexical_cast<double>(value));
any = boost::lexical_cast<double>(value);
} else if (cpp_type == IfcUtil::Argument_BOOL) {
v->set(boost::to_lower_copy(value) == "true");
any = boost::to_lower_copy(value) == "true";
} else if (cpp_type == IfcUtil::Argument_AGGREGATE_OF_INT) {
v->set(split<int>(value));
any = split<int>(value);
} else if (cpp_type == IfcUtil::Argument_AGGREGATE_OF_DOUBLE) {
v->set(split<double>(value));
any = split<double>(value);
}
if (v->isNull()) {
if (any.empty()) {
Logger::Error("Attribute '" + value + "' not successfully parsed");
delete v;
v = nullptr;
}
return v;
return any;
}
static void end_element(void* user, const xmlChar* tag) {
@@ -248,17 +271,20 @@ static void end_element(void* user, const xmlChar* tag) {
if (!state->stack.empty() && state->stack.back().ntype() == stack_node::node_aggregate) {
const auto& back = state->stack.back();
auto& elems = state->stack.back().aggregate_elements;
/*
auto* list = new IfcParse::ArgumentList(elems.size());
size_t i = 0;
for (auto& elem : elems) {
list->arguments()[i++] = elem;
}
back.inst()->data().attributes()[back.idx()] = list;
*/
// @todo
// back.inst()->data().storage_.set(back.idx(), elems);
}
if (state->dialect == ifcxml_dialect_ifc2x3 && state->stack.back().ntype() == stack_node::node_instance) {
if (state->stack.back().inst() != nullptr) {
state->idmap[state->stack.back().id()] = state->file->addEntity(state->stack.back().inst())->data().id();
state->idmap[state->stack.back().id()] = state->file->addEntity(state->stack.back().inst())->id();
}
}
@@ -290,15 +316,17 @@ static void process_characters(void* user, const xmlChar* character, int len) {
if (!state->stack.empty() && state->stack.back().inst() != nullptr && (state->stack.back().inst()->declaration().as_type_declaration() != nullptr)) {
const auto* pt = state->stack.back().inst()->declaration().as_type_declaration()->declared_type();
Argument* val = nullptr;
boost::any val;
try {
val = parse_attribute_value(pt, txt);
} catch (const std::exception& e) {
Logger::Error(e, state->stack.back().inst());
}
if (val != nullptr) {
if (!val.empty()) {
// type declaration always at idx 0
state->stack.back().inst()->data().setArgument(0, val);
visit_any([&state](auto& v) {
state->stack.back().inst()->data().storage_.set(0, v);
}, val);
}
} else if (state_type == stack_node::node_header_entry) {
const std::string tagname = boost::replace_all_copy(state->stack.back().tagname(), "ex:", "");
@@ -326,15 +354,17 @@ static void process_characters(void* user, const xmlChar* character, int len) {
const auto* pt = state->stack.back().inst()->declaration().as_entity()->attribute_by_index(state->stack.back().idx())->type_of_attribute();
auto cpp_type = IfcUtil::from_parameter_type(pt);
if (cpp_type != IfcUtil::Argument_ENTITY_INSTANCE) {
auto* val = parse_attribute_value(pt, txt);
if (val != nullptr) {
state->stack.back().inst()->data().setArgument(state->stack.back().idx(), val);
auto val = parse_attribute_value(pt, txt);
if (!val.empty()) {
visit_any([&state](auto& v) {
state->stack.back().inst()->data().setArgument(state->stack.back().idx(), v);
}, val);
}
}
} else if (state_type == stack_node::node_aggregate_element) {
const auto* pt = state->stack.back().aggregate_elem_type();
auto* val = parse_attribute_value(pt, txt);
if (val != nullptr) {
auto val = parse_attribute_value(pt, txt);
if (!val.empty()) {
(*(state->stack.rbegin() + 1)).aggregate_elements.push_back(val);
}
}
@@ -388,13 +418,11 @@ static void start_element(void* user, const xmlChar* tag, const xmlChar** attrs)
std::string schema_name(&it->front(), it->size());
boost::to_upper(schema_name);
state->file = new IfcParse::IfcFile(IfcParse::schema_by_name(schema_name));
state->file->parsing_complete() = false;
state->dialect = ifcxml_dialect_ifc4;
}
goto end;
} else if (tagname == "ex:iso_10303_28" && attrname == "xsi:schemaLocation" && boost::starts_with(value, "http://www.iai-tech.org/ifcXML/IFC2x3")) {
state->file = new IfcParse::IfcFile(IfcParse::schema_by_name("IFC2X3"));
state->file->parsing_complete() = false;
state->dialect = ifcxml_dialect_ifc2x3;
goto end;
}
@@ -426,7 +454,6 @@ static void start_element(void* user, const xmlChar* tag, const xmlChar** attrs)
state->forward_references.push_back(std::make_tuple(inst->as<IfcUtil::IfcBaseEntity>(), attribute_index, boost::get<std::string>(inst_or_ref)));
} else {
inst = boost::get<IfcUtil::IfcBaseClass*>(inst_or_ref);
// wattr->set(inst);
inst->set_attribute_value(attribute_index, inst);
}
};
@@ -452,7 +479,7 @@ static void start_element(void* user, const xmlChar* tag, const xmlChar** attrs)
}
}
auto* untyped = new IfcEntityInstanceData(decl);
auto untyped = IfcEntityInstanceData(storage_t(decl->as_entity() ? decl->as_entity()->attribute_count() : 1));
const IfcParse::entity* entity = decl->as_entity();
if (entity != nullptr) {
@@ -464,9 +491,11 @@ static void start_element(void* user, const xmlChar* tag, const xmlChar** attrs)
auto idx = entity->attribute_index(pair.first);
if (idx != -1) {
const auto* attr = entity->attribute_by_index(idx);
auto* val = parse_attribute_value(attr->type_of_attribute(), pair.second);
if (val != nullptr) {
untyped->setArgument(idx, val);
auto val = parse_attribute_value(attr->type_of_attribute(), pair.second);
if (!val.empty()) {
visit_any([&untyped, idx](auto& v) {
untyped->data().storage_->set_attribute_value(idx, v);
}, val);
}
} else {
Logger::Error("Unknown attribute '" + pair.first + "' on entity '" + entity->name() + "' with value '" + pair.second + "'");
@@ -474,7 +503,7 @@ static void start_element(void* user, const xmlChar* tag, const xmlChar** attrs)
}
}
IfcUtil::IfcBaseClass* newinst = state->file->schema()->instantiate(untyped);
IfcUtil::IfcBaseClass* newinst = state->file->schema()->instantiate(decl->name(), std::move(untyped));
if (state->dialect == ifcxml_dialect_ifc4) {
// In IFC2X3 not added directly because attrs such as GlobalId are in
@@ -532,9 +561,10 @@ static void start_element(void* user, const xmlChar* tag, const xmlChar** attrs)
if (decl != nullptr) {
auto inst_or_ref = create_instance(decl);
IfcUtil::IfcBaseClass* inst;
Argument* attr;
instance_to_attribute(inst_or_ref, attr, inst);
state->stack.back().aggregate_elements.push_back(attr);
// Argument* attr;
// @todo
// instance_to_attribute(inst_or_ref, attr, inst);
state->stack.back().aggregate_elements.push_back(boost::any{});
state->stack.push_back(stack_node::instance(id, inst));
}
}
@@ -558,14 +588,11 @@ static void start_element(void* user, const xmlChar* tag, const xmlChar** attrs)
if ((*found)->bound1() == 0 && (*found)->bound2() == 1) {
auto inst_or_ref = create_instance((*found)->entity_reference());
IfcUtil::IfcBaseClass* inst;
Argument* attr;
instance_to_attribute(inst_or_ref, attr, inst);
instance_to_attribute(inst_or_ref, 0, inst);
if (inst != nullptr) {
int idx = (*found)->entity_reference()->attribute_index(
(*found)->attribute_reference());
IfcWrite::IfcWriteArgument* attr_inv = new IfcWrite::IfcWriteArgument();
attr_inv->set(state->stack.back().inst());
inst->data().setArgument(idx, attr_inv);
inst->data().storage_.set(idx, state->stack.back().inst());
state->stack.push_back(stack_node::instance(id, inst));
} else {
Logger::Error("Unknown attribute " + tagname);
@@ -588,11 +615,11 @@ static void start_element(void* user, const xmlChar* tag, const xmlChar** attrs)
if (IfcUtil::from_parameter_type(attribute_type) == IfcUtil::Argument_ENTITY_INSTANCE) {
if (const auto* entity = attribute_type->as_named_type()->declared_type()->as_entity()) {
auto inst_or_reference = create_instance(entity);
Argument* attr;
IfcUtil::IfcBaseClass* newinst;
instance_to_attribute(inst_or_reference, attr, newinst);
state->stack.back().inst()->data().setArgument(idx, attr);
state->stack.push_back(stack_node::instance(id, newinst));
IfcUtil::IfcBaseClass* inst;
instance_to_attribute(inst_or_reference, idx, inst);
// @todo
state->stack.back().inst();
state->stack.push_back(stack_node::instance(id, boost::get<IfcUtil::IfcBaseClass*>(inst_or_reference)));
} else if (attribute_type->as_named_type()->declared_type()->as_select_type() != nullptr) {
// Select types cause an additional indirection, so the current stack node is simply repeated
state->stack.push_back(stack_node::select(state->stack.back().inst(), idx));
@@ -630,21 +657,18 @@ static void start_element(void* user, const xmlChar* tag, const xmlChar** attrs)
auto inst_or_ref = create_instance(decl);
IfcUtil::IfcBaseClass* inst;
Argument* attr;
instance_to_attribute(inst_or_ref, attr, inst);
instance_to_attribute(inst_or_ref, state->stack.back().idx(), inst);
if (state_type == stack_node::node_inverse) {
int idx = state->stack.back().inv_attr()->entity_reference()->attribute_index(
state->stack.back().inv_attr()->attribute_reference());
IfcWrite::IfcWriteArgument* attr_inv = new IfcWrite::IfcWriteArgument();
attr_inv->set(state->stack.back().inst());
if (inst != nullptr) {
inst->data().setArgument(idx, attr_inv);
inst->data().storage_.set(idx, state->stack.back().inst());
} else {
Logger::Error("Internal error, inverse attribute not processed");
}
} else if (state_type == stack_node::node_instance_attribute) {
state->stack.back().inst()->data().attributes()[state->stack.back().idx()] = attr;
state->stack.back().inst()->data().storage_.set(state->stack.back().idx(), inst);
}
if (entity == nullptr) {
@@ -679,16 +703,18 @@ IFC_PARSE_API IfcParse::IfcFile* IfcParse::parse_ifcxml(const std::string& filen
xmlSAXUserParseFile(&handler, &state, filename.c_str());
for (const auto& pair : state.forward_references) {
/*
auto it = state.idmap.find(pair.second);
if (it == state.idmap.end()) {
Logger::Error("Instance with id '" + pair.second + "' not encountered");
} else {
pair.first->set(state.file->instance_by_id(it->second));
}
*/
}
if (state.file != nullptr) {
state.file->parsing_complete() = true;
// state.file->parsing_complete() = true;
state.file->build_inverses();
}
+29 -4
View File
@@ -59,7 +59,10 @@ namespace impl {
// Base case: When the first type in the pack is the type we're looking for, or is a base class of it
template <typename T, typename U, typename... Ts>
struct TypeIndex<T, U, Ts...>
: std::integral_constant<std::size_t, std::is_base_of<U, T>::value ? 0 : 1 + TypeIndex<T, Ts...>::value> {};
: std::integral_constant<std::size_t, (std::is_pointer_v<T> ? std::is_base_of_v<std::remove_pointer_t<U>, std::remove_pointer_t<T>> : std::is_same_v<T, U>) ? 0 :
(TypeIndex<T, Ts...>::value == std::numeric_limits<std::size_t>::max()
? std::numeric_limits<std::size_t>::max()
: 1 + TypeIndex<T, Ts...>::value)> {};
// Recursion termination: When the parameter pack is empty
template <typename T>
@@ -117,6 +120,7 @@ namespace impl {
struct make_union_from_tuple<std::tuple<Args...>> {
using type = typename std::aligned_union<0, Args...>::type;
};
}
template<typename... Types>
@@ -165,15 +169,17 @@ public:
template<typename T, typename = std::enable_if_t<!std::is_same_v<std::decay_t<T>, VariantArray>>>
void set(std::size_t index, T&& value) {
using U = std::decay_t<T>;
static_assert(impl::TypeIndex_v<U, Types...> < sizeof...(Types), "Type not supported by variant");
if (index >= size_and_indices_[0]) {
throw std::out_of_range("Index out of range");
}
destroy_at_index(index);
using U = std::decay_t<T>;
size_and_indices_[index + 1] = impl::TypeIndex_v<U, Types...>;
using V = typename std::tuple_element<impl::TypeIndex_v<U, Types...>, impl::MapTypes_t<Types... >>::type;
// std::wcout << "setting " << index << " to " << typeid(V).name() << " (" << impl::TypeIndex_v<U, Types...> << ")" << std::endl;
if constexpr (impl::is_unique_ptr<V>::value) {
new(&storage_[index]) V(new U(value));
} else {
@@ -194,7 +200,12 @@ public:
if (!has<T>(index)) {
throw std::bad_cast();
}
return *reinterpret_cast<T*>(&storage_[index]);
using V = typename std::tuple_element<impl::TypeIndex_v<T, Types...>, impl::MapTypes_t<Types... >>::type;
if constexpr (impl::is_unique_ptr<V>::value) {
return **reinterpret_cast<V*>(&storage_[index]);
} else {
return *reinterpret_cast<V*>(&storage_[index]);
}
}
template<typename T>
@@ -207,7 +218,12 @@ public:
if (size_and_indices_[index + 1] != impl::TypeIndex<T, Types...>::value) {
throw std::bad_cast();
}
return *reinterpret_cast<const T*>(&storage_[index]);
using V = typename std::tuple_element<impl::TypeIndex_v<T, Types...>, impl::MapTypes_t<Types... >>::type;
if constexpr (impl::is_unique_ptr<V>::value) {
return **reinterpret_cast<const V*>(&storage_[index]);
} else {
return *reinterpret_cast<const V*>(&storage_[index]);
}
}
template<typename Visitor>
@@ -267,9 +283,18 @@ private:
return apply_visitor_impl(std::forward<Visitor>(visitor), idx, std::integral_constant<std::size_t, Index - 1>{});
}
template<typename, typename = std::void_t<>>
struct has_result_type : std::false_type {};
template<typename T>
struct has_result_type<T, std::void_t<typename T::result_type>> : std::true_type {};
template<typename Visitor>
auto apply_visitor_impl(Visitor&&, std::size_t, std::integral_constant<std::size_t, 0>) const {
throw std::runtime_error("Invalid variant index");
// This raises a warning but is neccessary (?) for the auto return type inference?
if constexpr (has_result_type<Visitor>::value) {
return typename Visitor::result_type{};
}
}
};
+4 -4
View File
@@ -417,11 +417,11 @@ std::string ColladaSerializer::differentiateSlabTypes(const IfcUtil::IfcBaseEnti
{
auto value = slab->get("PredefinedType");
if (value->isNull()) {
if (value.isNull()) {
return "_Unknown";
}
const std::string str_value = *value;
const std::string str_value = value;
std::string result;
if (str_value == "FLOOR") {
@@ -436,10 +436,10 @@ std::string ColladaSerializer::differentiateSlabTypes(const IfcUtil::IfcBaseEnti
result = "_NotDefined";
} else {
auto otype = slab->get("ObjectType");
if (otype->isNull()) {
if (otype.isNull()) {
result = "_Unknown";
} else {
result = (std::string) *otype;
result = (std::string) otype;
}
}
+1 -1
View File
@@ -542,7 +542,7 @@ void HdfSerializer::write_style(surface_style_serialization& data, const ifcopen
data.name = s.name.c_str();
// @todo
data.original_name = s.name.c_str();
data.id = s.instance->data().id();
data.id = s.instance->as<IfcUtil::IfcBaseClass>()->id();
if (s.diffuse) {
data.diffuse[0] = s.diffuse.ccomponents()(0);
data.diffuse[1] = s.diffuse.ccomponents()(1);
+46 -46
View File
@@ -382,7 +382,7 @@ namespace {
for (const auto& p : o->parents()) {
if (p->type() == "IfcBuildingStorey") {
try {
double e = *p->product()->get("Elevation");
double e = p->product()->get("Elevation");
double storey_elevation = e * o->geometry().settings().get<ifcopenshell::geometry::settings::LengthUnit>().get();
return std::make_pair(p->product(), storey_elevation);
} catch (...) {
@@ -495,22 +495,22 @@ namespace {
auto rels = product->get_inverse("IsDefinedBy");
for (auto& rel : *rels) {
if (rel->declaration().is("IfcRelDefinesByProperties")) {
auto pset = (IfcUtil::IfcBaseEntity*) (IfcUtil::IfcBaseClass*) *((IfcUtil::IfcBaseEntity*) rel)->get("RelatingPropertyDefinition");
auto pset = ((IfcUtil::IfcBaseClass*) ((IfcUtil::IfcBaseEntity*) rel)->get("RelatingPropertyDefinition"))->as<IfcUtil::IfcBaseEntity>();
std::string pset_name;
if (!pset->get("Name")->isNull()) {
pset_name = (std::string) *pset->get("Name");
if (!pset->get("Name").isNull()) {
pset_name = (std::string) pset->get("Name");
}
aggregate_of_instance::ptr props = *pset->get("HasProperties");
aggregate_of_instance::ptr props = pset->get("HasProperties");
for (auto& prop : *props) {
if (prop->declaration().is("IfcPropertySingleValue")) {
std::string name = *((IfcUtil::IfcBaseEntity*) prop)->get("Name");
if (((IfcUtil::IfcBaseEntity*) prop)->get("NominalValue")->isNull()) {
std::string name = ((IfcUtil::IfcBaseEntity*) prop)->get("Name");
if (((IfcUtil::IfcBaseEntity*) prop)->get("NominalValue").isNull()) {
continue;
}
IfcUtil::IfcBaseClass* v = *((IfcUtil::IfcBaseEntity*) prop)->get("NominalValue");
auto value = v->data().getArgument(0);
if (value->type() == IfcUtil::Argument_STRING) {
std::string v_str = *value;
IfcUtil::IfcBaseClass* v = ((IfcUtil::IfcBaseEntity*) prop)->get("NominalValue");
auto value = v->data().get_attribute_value(0);
if (value.type() == IfcUtil::Argument_STRING) {
std::string v_str = value;
*output_it++ = string_property{ pset_name, name, v_str };
}
}
@@ -525,12 +525,12 @@ namespace {
auto refs = item->get_inverse("StyledByItem");
for (auto& ref : *refs) {
if (ref->declaration().is("IfcStyledItem")) {
aggregate_of_instance::ptr styles = *((IfcUtil::IfcBaseEntity*)ref)->get("Styles");
aggregate_of_instance::ptr styles = ((IfcUtil::IfcBaseEntity*)ref)->get("Styles");
for (auto& s_ : *styles) {
auto s = (IfcUtil::IfcBaseEntity*) s_;
std::vector<IfcUtil::IfcBaseEntity*> pss;
if (s->declaration().is("IfcPresentationStyleAssignment")) {
aggregate_of_instance::ptr pstyles = *s->get("Styles");
aggregate_of_instance::ptr pstyles = s->get("Styles");
for (auto& ssss : *pstyles) {
pss.push_back((IfcUtil::IfcBaseEntity*) ssss);
}
@@ -540,8 +540,8 @@ namespace {
for (auto& ps : pss) {
if (ps->declaration().is("IfcCurveStyle")) {
auto arg = ps->get("Name");
if (!arg->isNull()) {
return (std::string) *arg;
if (!arg.isNull()) {
return (std::string) arg;
}
}
}
@@ -555,8 +555,8 @@ namespace {
void SvgSerializer::write(const IfcGeom::BRepElement* brep_obj) {
boost::optional<std::string> object_type;
if (!brep_obj->product()->get("ObjectType")->isNull()) {
object_type = static_cast<std::string>(*brep_obj->product()->get("ObjectType"));
if (!brep_obj->product()->get("ObjectType").isNull()) {
object_type = static_cast<std::string>(brep_obj->product()->get("ObjectType"));
}
std::vector<boost::optional<std::vector<double>>> dash_arrays;
@@ -845,11 +845,11 @@ void SvgSerializer::write(const geometry_data& data) {
}
for (auto& rel : *rels) {
if (rel->declaration().name() == "IfcRelDefinesByType") {
IfcUtil::IfcBaseClass* ty = *((IfcUtil::IfcBaseEntity*)rel)->get("RelatingType");
IfcUtil::IfcBaseClass* ty = ((IfcUtil::IfcBaseEntity*)rel)->get("RelatingType");
const std::string& ty_entity_name = ty->declaration().name();
// Damn you, IFC
if (ty_entity_name == "IfcDoorStyle" || ty_entity_name == "IfcDoorType") {
operation_type = (std::string)*((IfcUtil::IfcBaseEntity*)ty)->get("OperationType");
operation_type = (std::string)((IfcUtil::IfcBaseEntity*)ty)->get("OperationType");
}
}
}
@@ -1273,8 +1273,8 @@ void SvgSerializer::write(const geometry_data& data) {
std::string object_type;
auto ot_arg = data.product->get("ObjectType");
if (!ot_arg->isNull()) {
object_type = (std::string) *ot_arg;
if (!ot_arg.isNull()) {
object_type = (std::string) ot_arg;
object_type.erase(std::remove_if(object_type.begin(), object_type.end(), [](char c) { return !std::isalnum(c); }), object_type.end());
}
@@ -1476,8 +1476,8 @@ void SvgSerializer::write(const geometry_data& data) {
const double lu = file->getUnit("LENGTHUNIT").second;
auto a = data.product->get("Elevation");
if (!a->isNull()) {
double elev = *a;
if (!a.isNull()) {
double elev = a;
// @nb we don't actually factor in the length unit.
// elev *= lu;
@@ -1622,8 +1622,8 @@ void SvgSerializer::write(const geometry_data& data) {
}
if (print_space_names_ && data.product->declaration().is("IfcSpace")) {
auto attr = data.product->get("LongName");
if (!attr->isNull()) {
std::string long_name = *attr;
if (!attr.isNull()) {
std::string long_name = attr;
if (!long_name.empty()) {
labels.insert(labels.begin(), long_name);
}
@@ -1851,14 +1851,14 @@ void SvgSerializer::addTextAnnotations(const drawing_key& k) {
auto ds = ann->get("Description");
auto pl = ann->get("ObjectPlacement");
if (!ot->isNull() && !nm->isNull() && !ds->isNull() && !pl->isNull()) {
auto object_type = (std::string) *ot;
auto name = (std::string) *nm;
auto desc = (std::string) *ds;
if (!ot.isNull() && !nm.isNull() && !ds.isNull() && !pl.isNull()) {
auto object_type = (std::string) ot;
auto name = (std::string) nm;
auto desc = (std::string) ds;
if (object_type == "Text") {
auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(file, geometry_settings_);
auto item = mapping->map(*pl);
auto item = mapping->map(pl);
auto matrix = ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::matrix4>(item);
delete mapping;
if (item) {
@@ -2085,8 +2085,8 @@ void SvgSerializer::finalize() {
for (auto& s : *storeys) {
auto storey = (IfcUtil::IfcBaseEntity*) s;
auto a = storey->get("Elevation");
if (!a->isNull()) {
double elev = *a;
if (!a.isNull()) {
double elev = a;
elev *= lu;
auto svg_name = nameElement(storey);
@@ -2117,8 +2117,8 @@ void SvgSerializer::finalize() {
B.Add(C, mf.Face());
std::string name;
auto a2 = storey->get("Name");
if (!a2->isNull()) {
name = (std::string) *a2;
if (!a2.isNull()) {
name = (std::string) a2;
}
write(geometry_data{
C,{boost::none},trsf,storey,storey,elev,name,nameElement(storey)
@@ -2280,12 +2280,12 @@ std::string SvgSerializer::idElement(const IfcUtil::IfcBaseEntity* elem) {
const std::string type = elem->declaration().is("IfcBuildingStorey") ? "storey" : "product";
const std::string name =
(settings().get<ifcopenshell::geometry::settings::UseElementGuids>().get()
? static_cast<std::string>(*elem->get("GlobalId"))
: ((settings().get<ifcopenshell::geometry::settings::UseElementNames>().get() && !elem->get("Name")->isNull()))
? static_cast<std::string>(*elem->get("Name"))
? static_cast<std::string>(elem->get("GlobalId"))
: ((settings().get<ifcopenshell::geometry::settings::UseElementNames>().get() && !elem->get("Name").isNull()))
? static_cast<std::string>(elem->get("Name"))
: (settings().get<ifcopenshell::geometry::settings::UseElementStepIds>().get())
? ("id-" + boost::lexical_cast<std::string>(elem->data().id()))
: IfcParse::IfcGlobalId(*elem->get("GlobalId")).formatted());
? ("id-" + boost::lexical_cast<std::string>(elem->id()))
: IfcParse::IfcGlobalId(elem->get("GlobalId")).formatted());
return type + "-" + name;
}
@@ -2294,8 +2294,8 @@ std::string SvgSerializer::nameElement(const IfcUtil::IfcBaseEntity* elem) {
const std::string& entity = elem->declaration().name();
std::string ifc_name;
if (!elem->get("Name")->isNull()) {
ifc_name = (std::string) *elem->get("Name");
if (!elem->get("Name").isNull()) {
ifc_name = (std::string) elem->get("Name");
IfcUtil::escape_xml(ifc_name);
}
@@ -2303,7 +2303,7 @@ std::string SvgSerializer::nameElement(const IfcUtil::IfcBaseEntity* elem) {
{"id", idElement(elem)},
{"class", entity},
{namespace_prefix_ + "name", ifc_name},
{namespace_prefix_ + "guid", *elem->get("GlobalId")}
{namespace_prefix_ + "guid", elem->get("GlobalId")}
});
}
@@ -2322,8 +2322,8 @@ void SvgSerializer::setFile(IfcParse::IfcFile* f) {
if (insts) {
for (auto jt = insts->begin(); jt != insts->end(); ++jt) {
IfcUtil::IfcBaseEntity* product = (IfcUtil::IfcBaseEntity*) *jt;
if (!product->get("ObjectPlacement")->isNull()) {
auto item = mapping->map(*product->get("ObjectPlacement"));
if (!product->get("ObjectPlacement").isNull()) {
auto item = mapping->map(product->get("ObjectPlacement"));
auto matrix = ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::matrix4>(item);
gp_Trsf trsf;
if (matrix) {
@@ -2363,10 +2363,10 @@ void SvgSerializer::setSectionHeightsFromStoreys(double offset) {
if (storeys && storeys->size() > 0) {
for (auto& s : *storeys) {
auto attr_value = ((IfcUtil::IfcBaseEntity*)s)->get("Elevation");
if (!attr_value->isNull()) {
if (!attr_value.isNull()) {
double elev;
try {
elev = *attr_value;
elev = attr_value;
} catch (std::exception& e) {
Logger::Error(e);
continue;
+6 -6
View File
@@ -77,12 +77,12 @@ struct storey_sorter {
if (a_is_storey && b_is_storey) {
boost::optional<double> a_elev, b_elev;
try {
a_elev = static_cast<double>(*a->get("Elevation"));
b_elev = static_cast<double>(*b->get("Elevation"));
a_elev = static_cast<double>(a->get("Elevation"));
b_elev = static_cast<double>(b->get("Elevation"));
} catch (...) {};
if (a_elev && b_elev) {
if (std::equal_to<double>()(*a_elev, *b_elev)) {
return std::less<unsigned int>()(a->data().id(), b->data().id());
return std::less<unsigned int>()(a->id(), b->id());
} else {
return std::less<double>()(*a_elev, *b_elev);
}
@@ -90,12 +90,12 @@ struct storey_sorter {
boost::optional<std::string> a_name, b_name;
try {
a_name = static_cast<std::string>(*a->get("Name"));
b_name = static_cast<std::string>(*b->get("Name"));
a_name = static_cast<std::string>(a->get("Name"));
b_name = static_cast<std::string>(b->get("Name"));
} catch (...) {};
if (a_name && b_name) {
if (std::equal_to<std::string>()(*a_name, *b_name)) {
return std::less<unsigned int>()(a->data().id(), b->data().id());
return std::less<unsigned int>()(a->id(), b->id());
} else {
return std::less<std::string>()(*a_name, *b_name);
}
@@ -57,7 +57,7 @@ std::map<std::string, std::string> POSTFIX_SCHEMA(argument_name_map);
// Format an IFC attribute and maybe returns as string. Only literal scalar
// values are converted. Things like entity instances and lists are omitted.
boost::optional<std::string> format_attribute(ifcopenshell::geometry::abstract_mapping* mapping, const Argument* argument, IfcUtil::ArgumentType argument_type, const std::string& argument_name) {
boost::optional<std::string> format_attribute(ifcopenshell::geometry::abstract_mapping* mapping, AttributeValue argument, IfcUtil::ArgumentType argument_type, const std::string& argument_name) {
boost::optional<std::string> value;
// Hard-code lat-lon as it represents an array
@@ -65,7 +65,7 @@ boost::optional<std::string> format_attribute(ifcopenshell::geometry::abstract_m
if (argument_name == "IfcSite.RefLatitude" ||
argument_name == "IfcSite.RefLongitude")
{
std::vector<int> angle = *argument;
std::vector<int> angle = argument;
double deg;
if (angle.size() >= 3) {
deg = angle[0] + angle[1] / 60. + angle[2] / 3600.;
@@ -83,30 +83,30 @@ boost::optional<std::string> format_attribute(ifcopenshell::geometry::abstract_m
switch(argument_type) {
case IfcUtil::Argument_BOOL: {
const bool b = *argument;
const bool b = argument;
value = b ? "true" : "false";
break; }
case IfcUtil::Argument_DOUBLE: {
const double d = *argument;
const double d = argument;
std::stringstream stream;
stream << std::setprecision (std::numeric_limits< double >::max_digits10) << d;
value = stream.str();
break; }
case IfcUtil::Argument_STRING:
case IfcUtil::Argument_ENUMERATION: {
value = static_cast<std::string>(*argument);
value = static_cast<std::string>(argument);
break; }
case IfcUtil::Argument_INT: {
const int v = *argument;
const int v = argument;
std::stringstream stream;
stream << v;
value = stream.str();
break; }
case IfcUtil::Argument_ENTITY_INSTANCE: {
IfcUtil::IfcBaseClass* e = *argument;
IfcUtil::IfcBaseClass* e = argument;
if (!e->declaration().as_entity()) {
IfcUtil::IfcBaseType* f = e->as<IfcUtil::IfcBaseType>();
value = format_attribute(mapping, f->data().getArgument(0), f->data().getArgument(0)->type(), argument_name);
value = format_attribute(mapping, f->data().get_attribute_value(0), f->data().get_attribute_value(0).type(), argument_name);
} else if (e->declaration().is(IfcSchema::IfcSIUnit::Class()) || e->declaration().is(IfcSchema::IfcConversionBasedUnit::Class())) {
// Some string concatenation to have a unit name as a XML attribute.
@@ -155,13 +155,13 @@ ptree* format_entity_instance(ifcopenshell::geometry::abstract_mapping* mapping,
const unsigned n = instance->declaration().attribute_count();
for (unsigned i = 0; i < n; ++i) {
try {
instance->data().getArgument(i);
instance->data().get_attribute_value(i);
} catch (const std::exception&) {
Logger::Error("Expected " + boost::lexical_cast<std::string>(n) + " attributes for:", instance);
break;
}
const Argument* argument = instance->data().getArgument(i);
if (argument->isNull()) continue;
auto argument = instance->data().get_attribute_value(i);
if (argument.isNull()) continue;
std::string argument_name = instance->declaration().attribute_by_index(i)->name();
std::map<std::string, std::string>::const_iterator argument_name_it;
@@ -169,7 +169,7 @@ ptree* format_entity_instance(ifcopenshell::geometry::abstract_mapping* mapping,
if (argument_name_it != POSTFIX_SCHEMA(argument_name_map).end()) {
argument_name = argument_name_it->second;
}
const IfcUtil::ArgumentType argument_type = instance->data().getArgument(i)->type();
const IfcUtil::ArgumentType argument_type = instance->data().get_attribute_value(i).type();
const std::string qualified_name = instance->declaration().name() + "." + argument_name;
boost::optional<std::string> value;
@@ -202,7 +202,7 @@ ptree* format_entity_instance(ifcopenshell::geometry::abstract_mapping* mapping,
}
std::string qualify_unrooted_instance(IfcUtil::IfcBaseInterface* inst) {
return inst->declaration().name() + "_" + boost::lexical_cast<std::string>(inst->data().id());
return inst->declaration().name() + "_" + boost::lexical_cast<std::string>(inst->as<IfcUtil::IfcBaseEntity>()->id());
}
// A function to be called recursively. Template specialization is used