mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 18:16:40 +00:00
WIP
This commit is contained in:
@@ -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
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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.);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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_));
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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{};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user