mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-23 05:18:36 +00:00
Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f40d147830 | |||
| f0ecf2d3d5 | |||
| 246989170c | |||
| c143546903 | |||
| 6052f48b88 | |||
| 0445110778 | |||
| c032178753 | |||
| 09d9c6bd4b | |||
| 27cd362568 | |||
| 2da34deaf1 | |||
| 4f0297d8b2 | |||
| 74a2d50d97 | |||
| 9c38a7c58b | |||
| 8b8663eb8e | |||
| 43becceb94 | |||
| 4ba253a19b | |||
| f9a02829b6 | |||
| 7d2066e7c2 | |||
| 1534e7962e | |||
| 952ba717e6 | |||
| 600e9e0a4b | |||
| 0694d34707 | |||
| e5bb1b98ed | |||
| 3d8874559d | |||
| ad62a5fdef | |||
| e0f5adfb7e | |||
| fac13f1e1f | |||
| 2e27ff64b4 | |||
| 261fb895eb | |||
| 9c323f91dd | |||
| debb0f5e59 | |||
| 054ccf9a05 | |||
| 53e0f40cb9 |
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "../ifcparse/IfcFile.h"
|
||||
#include "../ifcparse/IfcLogger.h"
|
||||
#include "../ifcparse/Ifc2x3.h"
|
||||
|
||||
#include <boost/preprocessor/stringize.hpp>
|
||||
#include <boost/preprocessor/seq/for_each.hpp>
|
||||
@@ -79,31 +80,31 @@ struct is_ifc4_or_higher<T, std::void_t<decltype(T::IfcMaterialDefinition)>> : s
|
||||
|
||||
typedef std::map<std::string, std::map<std::string, std::string>> element_properties;
|
||||
|
||||
std::string format_string(const Argument* argument) {
|
||||
std::string format_string(const AttributeValue& argument) {
|
||||
// Argument is a runtime tagged variant for the various data types in a IFC model,
|
||||
// in this particular case we only care about flattening it to a string.
|
||||
// @todo mostly duplicated from XmlSerializer.cpp
|
||||
if (argument->isNull()) {
|
||||
if (argument.isNull()) {
|
||||
return "-";
|
||||
}
|
||||
auto argument_type = argument->type();
|
||||
auto argument_type = argument.type();
|
||||
switch (argument_type) {
|
||||
case IfcUtil::Argument_BOOL: {
|
||||
const bool b = *argument;
|
||||
const bool b = argument;
|
||||
return b ? "true" : "false";
|
||||
}
|
||||
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;
|
||||
return stream.str();
|
||||
break; }
|
||||
case IfcUtil::Argument_STRING:
|
||||
case IfcUtil::Argument_ENUMERATION: {
|
||||
return static_cast<std::string>(*argument);
|
||||
return static_cast<std::string>(argument);
|
||||
break; }
|
||||
case IfcUtil::Argument_INT: {
|
||||
const int v = *argument;
|
||||
const int v = argument;
|
||||
std::stringstream stream;
|
||||
stream << v;
|
||||
return stream.str();
|
||||
@@ -136,7 +137,7 @@ void process_pset(element_properties& props, const T* inst) {
|
||||
if (!singleval->NominalValue()) {
|
||||
propvalue = "-";
|
||||
} else {
|
||||
props[*pset->Name()][propname] = format_string(singleval->NominalValue()->template as<IfcUtil::IfcBaseClass>()->data().getArgument(0));
|
||||
props[*pset->Name()][propname] = format_string(singleval->NominalValue()->template as<IfcUtil::IfcBaseClass>()->data().get_attribute_value(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -148,8 +149,8 @@ void process_pset(element_properties& props, const T* inst) {
|
||||
auto qs = qset->Quantities();
|
||||
for (auto it = qs->begin(); it != qs->end(); ++it) {
|
||||
auto& q = *it;
|
||||
if (q->template as<typename Schema::IfcPhysicalSimpleQuantity>() && q->data().getArgument(3)->type() == IfcUtil::Argument_DOUBLE) {
|
||||
double v = *q->data().getArgument(3);
|
||||
if (q->template as<typename Schema::IfcPhysicalSimpleQuantity>() && q->data().get_attribute_value(3).type() == IfcUtil::Argument_DOUBLE) {
|
||||
double v = q->data().get_attribute_value(3);
|
||||
props[*qset->Name()][q->Name()] = std::to_string(v);
|
||||
}
|
||||
}
|
||||
@@ -264,7 +265,8 @@ int main(int argc, char** argv) {
|
||||
|
||||
for (auto it = elements->begin(); it != elements->end(); ++it) {
|
||||
const auto* element = *it;
|
||||
std::cout << element->data().toString() << std::endl;
|
||||
element->toString(std::cout);
|
||||
std::cout << std::endl;
|
||||
|
||||
const IfcSchema::IfcWindow* window;
|
||||
if ((window = element->as<IfcSchema::IfcWindow>()) != 0) {
|
||||
|
||||
@@ -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(decl, 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);
|
||||
}
|
||||
|
||||
+1
-1
Submodule src/ifcconvert/cityjson updated: ca39a6d81e...9e0bc8c2a8
@@ -471,7 +471,7 @@ struct intersection_validator {
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
ss << geom_object->product()->data().toString();
|
||||
geom_object->product()->toString(ss);
|
||||
auto sss = ss.str();
|
||||
std::wcout << sss.c_str() << std::endl;
|
||||
|
||||
|
||||
+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
|
||||
|
||||
@@ -408,7 +408,7 @@ bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, If
|
||||
TopoDS_Shape shape = BRepPrimAPI_MakeRevol(face, ax);
|
||||
|
||||
results.emplace_back(ConversionResult(
|
||||
r->instance->data().id(),
|
||||
r->instance->as<IfcUtil::IfcBaseEntity>()->id(),
|
||||
r->matrix,
|
||||
new OpenCascadeShape(shape),
|
||||
r->surface_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
|
||||
|
||||
@@ -528,7 +528,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;
|
||||
}
|
||||
@@ -303,7 +303,7 @@ const IfcUtil::IfcBaseEntity* mapping::get_single_material_association(const Ifc
|
||||
if (associated_material->as<IfcSchema::IfcMaterialLayerSetUsage>() || associated_material->as<IfcSchema::IfcMaterialLayerSet>()) {
|
||||
IfcSchema::IfcMaterialLayerSet* layerset;
|
||||
if (auto *m = associated_material->as<IfcSchema::IfcMaterialLayerSetUsage>()) {
|
||||
if (m->get("ForLayerSet")->isNull()) {
|
||||
if (m->get("ForLayerSet").isNull()) {
|
||||
Logger::Warning("Missing ForLayerSet for:", m);
|
||||
return nullptr;
|
||||
}
|
||||
@@ -322,7 +322,7 @@ const IfcUtil::IfcBaseEntity* mapping::get_single_material_association(const Ifc
|
||||
if (associated_material->as<IfcSchema::IfcMaterialProfileSetUsage>() || associated_material->as<IfcSchema::IfcMaterialProfileSet>()) {
|
||||
IfcSchema::IfcMaterialProfileSet* profileset;
|
||||
if (auto* m = associated_material->as<IfcSchema::IfcMaterialProfileSetUsage>()) {
|
||||
if (m->get("ForProfileSet")->isNull()) {
|
||||
if (m->get("ForProfileSet").isNull()) {
|
||||
Logger::Warning("Missing ForProfileSet for:", m);
|
||||
return nullptr;
|
||||
}
|
||||
@@ -523,7 +523,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;
|
||||
@@ -553,7 +553,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 << "-";
|
||||
}
|
||||
@@ -693,8 +693,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;
|
||||
@@ -827,11 +827,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;
|
||||
}
|
||||
|
||||
@@ -588,7 +588,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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ def parse(fn: str) -> mapping.Mapping:
|
||||
special = ((not_paren_star_quote_special | CaselessLiteral("(") | CaselessLiteral(")") | CaselessLiteral("*") | CaselessLiteral("\"\""))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="special"))("special")
|
||||
binary_literal = ((CaselessLiteral("%") + bit + ZeroOrMore(bit))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="binary_literal"))("binary_literal")
|
||||
integer_literal = (digits)("integer_literal")
|
||||
simple_id = ~CaselessKeyword("bag") + ~CaselessKeyword("lobound") + ~CaselessKeyword("aggregate") + ~CaselessKeyword("reference") + ~CaselessKeyword("abstract") + ~CaselessKeyword("value_unique") + ~CaselessKeyword("if") + ~CaselessKeyword("loindex") + ~CaselessKeyword("format") + ~CaselessKeyword("true") + ~CaselessKeyword("insert") + ~CaselessKeyword("exp") + ~CaselessKeyword("end_type") + ~CaselessKeyword("end") + ~CaselessKeyword("optional") + ~CaselessKeyword("in") + ~CaselessKeyword("like") + ~CaselessKeyword("type") + ~CaselessKeyword("end_rule") + ~CaselessKeyword("repeat") + ~CaselessKeyword("nvl") + ~CaselessKeyword("otherwise") + ~CaselessKeyword("procedure") + ~CaselessKeyword("number") + ~CaselessKeyword("boolean") + ~CaselessKeyword("exists") + ~CaselessKeyword("andor") + ~CaselessKeyword("alias") + ~CaselessKeyword("entity") + ~CaselessKeyword("constant") + ~CaselessKeyword("tan") + ~CaselessKeyword("or") + ~CaselessKeyword("oneof") + ~CaselessKeyword("from") + ~CaselessKeyword("escape") + ~CaselessKeyword("typeof") + ~CaselessKeyword("extensible") + ~CaselessKeyword("div") + ~CaselessKeyword("then") + ~CaselessKeyword("by") + ~CaselessKeyword("unknown") + ~CaselessKeyword("var") + ~CaselessKeyword("pi") + ~CaselessKeyword("inverse") + ~CaselessKeyword("skip") + ~CaselessKeyword("array") + ~CaselessKeyword("end_subtype_constraint") + ~CaselessKeyword("use") + ~CaselessKeyword("self") + ~CaselessKeyword("end_alias") + ~CaselessKeyword("select") + ~CaselessKeyword("for") + ~CaselessKeyword("sizeof") + ~CaselessKeyword("fixed") + ~CaselessKeyword("local") + ~CaselessKeyword("remove") + ~CaselessKeyword("enumeration") + ~CaselessKeyword("end_local") + ~CaselessKeyword("not") + ~CaselessKeyword("function") + ~CaselessKeyword("cos") + ~CaselessKeyword("logical") + ~CaselessKeyword("query") + ~CaselessKeyword("atan") + ~CaselessKeyword("return") + ~CaselessKeyword("schema") + ~CaselessKeyword("hiindex") + ~CaselessKeyword("rolesof") + ~CaselessKeyword("log10") + ~CaselessKeyword("end_function") + ~CaselessKeyword("abs") + ~CaselessKeyword("length") + ~CaselessKeyword("renamed") + ~CaselessKeyword("acos") + ~CaselessKeyword("end_case") + ~CaselessKeyword("case") + ~CaselessKeyword("mod") + ~CaselessKeyword("end_if") + ~CaselessKeyword("list") + ~CaselessKeyword("end_repeat") + ~CaselessKeyword("generic") + ~CaselessKeyword("of") + ~CaselessKeyword("supertype") + ~CaselessKeyword("false") + ~CaselessKeyword("end_entity") + ~CaselessKeyword("odd") + ~CaselessKeyword("integer") + ~CaselessKeyword("hibound") + ~CaselessKeyword("rule") + ~CaselessKeyword("as") + ~CaselessKeyword("derive") + ~CaselessKeyword("log") + ~CaselessKeyword("set") + ~CaselessKeyword("subtype_constraint") + ~CaselessKeyword("unique") + ~CaselessKeyword("value") + ~CaselessKeyword("subtype") + ~CaselessKeyword("until") + ~CaselessKeyword("with") + ~CaselessKeyword("sqrt") + ~CaselessKeyword("where") + ~CaselessKeyword("value_in") + ~CaselessKeyword("to") + ~CaselessKeyword("xor") + ~CaselessKeyword("sin") + ~CaselessKeyword("while") + ~CaselessKeyword("string") + ~CaselessKeyword("usedin") + ~CaselessKeyword("total_over") + ~CaselessKeyword("binary") + ~CaselessKeyword("and") + ~CaselessKeyword("end_schema") + ~CaselessKeyword("generic_entity") + ~CaselessKeyword("end_constant") + ~CaselessKeyword("const_e") + ~CaselessKeyword("based_on") + ~CaselessKeyword("else") + ~CaselessKeyword("asin") + ~CaselessKeyword("blength") + ~CaselessKeyword("real") + ~CaselessKeyword("end_procedure") + ~CaselessKeyword("log2") + ~CaselessKeyword("begin") + originalTextFor(Combine((letter + ZeroOrMore((letter | digit | CaselessLiteral("_"))))))("simple_id")
|
||||
simple_id = ~CaselessKeyword("generic") + ~CaselessKeyword("value") + ~CaselessKeyword("case") + ~CaselessKeyword("for") + ~CaselessKeyword("sin") + ~CaselessKeyword("value_unique") + ~CaselessKeyword("extensible") + ~CaselessKeyword("tan") + ~CaselessKeyword("local") + ~CaselessKeyword("string") + ~CaselessKeyword("procedure") + ~CaselessKeyword("derive") + ~CaselessKeyword("end_if") + ~CaselessKeyword("supertype") + ~CaselessKeyword("entity") + ~CaselessKeyword("oneof") + ~CaselessKeyword("constant") + ~CaselessKeyword("end_case") + ~CaselessKeyword("end_alias") + ~CaselessKeyword("unknown") + ~CaselessKeyword("total_over") + ~CaselessKeyword("div") + ~CaselessKeyword("type") + ~CaselessKeyword("true") + ~CaselessKeyword("end_repeat") + ~CaselessKeyword("unique") + ~CaselessKeyword("end_rule") + ~CaselessKeyword("number") + ~CaselessKeyword("end_function") + ~CaselessKeyword("where") + ~CaselessKeyword("self") + ~CaselessKeyword("usedin") + ~CaselessKeyword("end_type") + ~CaselessKeyword("logical") + ~CaselessKeyword("generic_entity") + ~CaselessKeyword("end_schema") + ~CaselessKeyword("xor") + ~CaselessKeyword("until") + ~CaselessKeyword("to") + ~CaselessKeyword("in") + ~CaselessKeyword("inverse") + ~CaselessKeyword("enumeration") + ~CaselessKeyword("var") + ~CaselessKeyword("value_in") + ~CaselessKeyword("const_e") + ~CaselessKeyword("use") + ~CaselessKeyword("exists") + ~CaselessKeyword("exp") + ~CaselessKeyword("while") + ~CaselessKeyword("if") + ~CaselessKeyword("fixed") + ~CaselessKeyword("subtype") + ~CaselessKeyword("format") + ~CaselessKeyword("as") + ~CaselessKeyword("and") + ~CaselessKeyword("rule") + ~CaselessKeyword("function") + ~CaselessKeyword("lobound") + ~CaselessKeyword("length") + ~CaselessKeyword("hiindex") + ~CaselessKeyword("log2") + ~CaselessKeyword("reference") + ~CaselessKeyword("skip") + ~CaselessKeyword("with") + ~CaselessKeyword("integer") + ~CaselessKeyword("sqrt") + ~CaselessKeyword("insert") + ~CaselessKeyword("nvl") + ~CaselessKeyword("log") + ~CaselessKeyword("boolean") + ~CaselessKeyword("from") + ~CaselessKeyword("rolesof") + ~CaselessKeyword("hibound") + ~CaselessKeyword("abs") + ~CaselessKeyword("like") + ~CaselessKeyword("pi") + ~CaselessKeyword("alias") + ~CaselessKeyword("not") + ~CaselessKeyword("repeat") + ~CaselessKeyword("based_on") + ~CaselessKeyword("subtype_constraint") + ~CaselessKeyword("asin") + ~CaselessKeyword("optional") + ~CaselessKeyword("list") + ~CaselessKeyword("abstract") + ~CaselessKeyword("mod") + ~CaselessKeyword("false") + ~CaselessKeyword("log10") + ~CaselessKeyword("loindex") + ~CaselessKeyword("aggregate") + ~CaselessKeyword("end_constant") + ~CaselessKeyword("end") + ~CaselessKeyword("sizeof") + ~CaselessKeyword("remove") + ~CaselessKeyword("acos") + ~CaselessKeyword("set") + ~CaselessKeyword("renamed") + ~CaselessKeyword("end_local") + ~CaselessKeyword("of") + ~CaselessKeyword("escape") + ~CaselessKeyword("begin") + ~CaselessKeyword("select") + ~CaselessKeyword("end_procedure") + ~CaselessKeyword("else") + ~CaselessKeyword("end_subtype_constraint") + ~CaselessKeyword("cos") + ~CaselessKeyword("real") + ~CaselessKeyword("query") + ~CaselessKeyword("odd") + ~CaselessKeyword("andor") + ~CaselessKeyword("return") + ~CaselessKeyword("then") + ~CaselessKeyword("end_entity") + ~CaselessKeyword("array") + ~CaselessKeyword("blength") + ~CaselessKeyword("or") + ~CaselessKeyword("typeof") + ~CaselessKeyword("binary") + ~CaselessKeyword("atan") + ~CaselessKeyword("by") + ~CaselessKeyword("otherwise") + ~CaselessKeyword("bag") + ~CaselessKeyword("schema") + originalTextFor(Combine((letter + ZeroOrMore((letter | digit | CaselessLiteral("_"))))))("simple_id")
|
||||
simple_string_literal = ((CaselessLiteral("'") + ZeroOrMore(((CaselessLiteral("'") + CaselessLiteral("'")) | not_quote)) + CaselessLiteral("'")))("simple_string_literal")
|
||||
abstract_entity_declaration = (ABSTRACT)("abstract_entity_declaration")
|
||||
abstract_supertype = ((ABSTRACT + SUPERTYPE + CaselessLiteral(";"))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="abstract_supertype"))("abstract_supertype")
|
||||
@@ -251,224 +251,224 @@ def parse(fn: str) -> mapping.Mapping:
|
||||
constructed_types = ((enumeration_type | select_type)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="constructed_types"))("constructed_types")
|
||||
reference_clause = ((REFERENCE + FROM + schema_ref + Optional((CaselessLiteral("(") + resource_or_rename + ZeroOrMore((CaselessLiteral(",") + resource_or_rename)) + CaselessLiteral(")"))) + CaselessLiteral(";"))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="reference_clause"))("reference_clause")
|
||||
interface_specification = ((reference_clause | use_clause)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="interface_specification"))("interface_specification")
|
||||
stmt = Forward()("stmt")
|
||||
general_aggregation_types = Forward()("general_aggregation_types")
|
||||
procedure_call_stmt = Forward()("procedure_call_stmt")
|
||||
inverse_attr = Forward()("inverse_attr")
|
||||
derived_attr = Forward()("derived_attr")
|
||||
width_spec = Forward()("width_spec")
|
||||
actual_parameter_list = Forward()("actual_parameter_list")
|
||||
type_decl = Forward()("type_decl")
|
||||
selector = Forward()("selector")
|
||||
abstract_supertype_declaration = Forward()("abstract_supertype_declaration")
|
||||
explicit_attr = Forward()("explicit_attr")
|
||||
aggregation_types = Forward()("aggregation_types")
|
||||
domain_rule = Forward()("domain_rule")
|
||||
entity_constructor = Forward()("entity_constructor")
|
||||
function_call = Forward()("function_call")
|
||||
numeric_expression = Forward()("numeric_expression")
|
||||
general_set_type = Forward()("general_set_type")
|
||||
qualifier = Forward()("qualifier")
|
||||
formal_parameter = Forward()("formal_parameter")
|
||||
index_1 = Forward()("index_1")
|
||||
underlying_type = Forward()("underlying_type")
|
||||
local_variable = Forward()("local_variable")
|
||||
aggregate_source = Forward()("aggregate_source")
|
||||
while_control = Forward()("while_control")
|
||||
interval_low = Forward()("interval_low")
|
||||
parameter = Forward()("parameter")
|
||||
precision_spec = Forward()("precision_spec")
|
||||
one_of = Forward()("one_of")
|
||||
subtype_constraint_body = Forward()("subtype_constraint_body")
|
||||
general_array_type = Forward()("general_array_type")
|
||||
list_type = Forward()("list_type")
|
||||
subtype_constraint_decl = Forward()("subtype_constraint_decl")
|
||||
schema_decl = Forward()("schema_decl")
|
||||
algorithm_head = Forward()("algorithm_head")
|
||||
query_expression = Forward()("query_expression")
|
||||
primary = Forward()("primary")
|
||||
repeat_control = Forward()("repeat_control")
|
||||
factor = Forward()("factor")
|
||||
procedure_head = Forward()("procedure_head")
|
||||
aggregate_type = Forward()("aggregate_type")
|
||||
supertype_factor = Forward()("supertype_factor")
|
||||
interval_item = Forward()("interval_item")
|
||||
subtype_constraint = Forward()("subtype_constraint")
|
||||
repeat_stmt = Forward()("repeat_stmt")
|
||||
entity_body = Forward()("entity_body")
|
||||
interval_high = Forward()("interval_high")
|
||||
logical_expression = Forward()("logical_expression")
|
||||
simple_expression = Forward()("simple_expression")
|
||||
subsuper = Forward()("subsuper")
|
||||
increment = Forward()("increment")
|
||||
remark = Forward()("remark")
|
||||
simple_factor = Forward()("simple_factor")
|
||||
case_stmt = Forward()("case_stmt")
|
||||
derive_clause = Forward()("derive_clause")
|
||||
supertype_constraint = Forward()("supertype_constraint")
|
||||
assignment_stmt = Forward()("assignment_stmt")
|
||||
entity_head = Forward()("entity_head")
|
||||
set_type = Forward()("set_type")
|
||||
instantiable_type = Forward()("instantiable_type")
|
||||
increment_control = Forward()("increment_control")
|
||||
local_variable = Forward()("local_variable")
|
||||
until_control = Forward()("until_control")
|
||||
while_control = Forward()("while_control")
|
||||
parameter = Forward()("parameter")
|
||||
width = Forward()("width")
|
||||
string_type = Forward()("string_type")
|
||||
array_type = Forward()("array_type")
|
||||
if_stmt = Forward()("if_stmt")
|
||||
index = Forward()("index")
|
||||
repetition = Forward()("repetition")
|
||||
index_qualifier = Forward()("index_qualifier")
|
||||
bound_1 = Forward()("bound_1")
|
||||
procedure_decl = Forward()("procedure_decl")
|
||||
entity_constructor = Forward()("entity_constructor")
|
||||
inverse_clause = Forward()("inverse_clause")
|
||||
function_head = Forward()("function_head")
|
||||
formal_parameter = Forward()("formal_parameter")
|
||||
interval_high = Forward()("interval_high")
|
||||
entity_decl = Forward()("entity_decl")
|
||||
abstract_supertype_declaration = Forward()("abstract_supertype_declaration")
|
||||
index_1 = Forward()("index_1")
|
||||
general_aggregation_types = Forward()("general_aggregation_types")
|
||||
real_type = Forward()("real_type")
|
||||
type_decl = Forward()("type_decl")
|
||||
stmt = Forward()("stmt")
|
||||
declaration = Forward()("declaration")
|
||||
binary_type = Forward()("binary_type")
|
||||
interval = Forward()("interval")
|
||||
explicit_attr = Forward()("explicit_attr")
|
||||
compound_stmt = Forward()("compound_stmt")
|
||||
aggregation_types = Forward()("aggregation_types")
|
||||
simple_factor = Forward()("simple_factor")
|
||||
where_clause = Forward()("where_clause")
|
||||
entity_head = Forward()("entity_head")
|
||||
underlying_type = Forward()("underlying_type")
|
||||
subtype_constraint_decl = Forward()("subtype_constraint_decl")
|
||||
logical_expression = Forward()("logical_expression")
|
||||
case_label = Forward()("case_label")
|
||||
expression = Forward()("expression")
|
||||
general_list_type = Forward()("general_list_type")
|
||||
actual_parameter_list = Forward()("actual_parameter_list")
|
||||
width_spec = Forward()("width_spec")
|
||||
selector = Forward()("selector")
|
||||
syntax = Forward()("syntax")
|
||||
aggregate_source = Forward()("aggregate_source")
|
||||
return_stmt = Forward()("return_stmt")
|
||||
embedded_remark = Forward()("embedded_remark")
|
||||
parameter_type = Forward()("parameter_type")
|
||||
term = Forward()("term")
|
||||
index = Forward()("index")
|
||||
expression = Forward()("expression")
|
||||
derived_attr = Forward()("derived_attr")
|
||||
repeat_control = Forward()("repeat_control")
|
||||
assignment_stmt = Forward()("assignment_stmt")
|
||||
bag_type = Forward()("bag_type")
|
||||
schema_body = Forward()("schema_body")
|
||||
until_control = Forward()("until_control")
|
||||
simple_types = Forward()("simple_types")
|
||||
subsuper = Forward()("subsuper")
|
||||
entity_decl = Forward()("entity_decl")
|
||||
concrete_types = Forward()("concrete_types")
|
||||
element = Forward()("element")
|
||||
general_bag_type = Forward()("general_bag_type")
|
||||
interval_item = Forward()("interval_item")
|
||||
inverse_attr = Forward()("inverse_attr")
|
||||
constant_body = Forward()("constant_body")
|
||||
increment = Forward()("increment")
|
||||
case_label = Forward()("case_label")
|
||||
case_action = Forward()("case_action")
|
||||
width = Forward()("width")
|
||||
procedure_decl = Forward()("procedure_decl")
|
||||
increment_control = Forward()("increment_control")
|
||||
index_qualifier = Forward()("index_qualifier")
|
||||
constant_decl = Forward()("constant_decl")
|
||||
supertype_rule = Forward()("supertype_rule")
|
||||
syntax = Forward()("syntax")
|
||||
function_head = Forward()("function_head")
|
||||
repetition = Forward()("repetition")
|
||||
if_stmt = Forward()("if_stmt")
|
||||
supertype_expression = Forward()("supertype_expression")
|
||||
inverse_clause = Forward()("inverse_clause")
|
||||
aggregate_initializer = Forward()("aggregate_initializer")
|
||||
return_stmt = Forward()("return_stmt")
|
||||
generalized_types = Forward()("generalized_types")
|
||||
bound_2 = Forward()("bound_2")
|
||||
real_type = Forward()("real_type")
|
||||
index_2 = Forward()("index_2")
|
||||
array_type = Forward()("array_type")
|
||||
local_decl = Forward()("local_decl")
|
||||
supertype_term = Forward()("supertype_term")
|
||||
where_clause = Forward()("where_clause")
|
||||
embedded_remark = Forward()("embedded_remark")
|
||||
compound_stmt = Forward()("compound_stmt")
|
||||
bound_1 = Forward()("bound_1")
|
||||
alias_stmt = Forward()("alias_stmt")
|
||||
subtype_constraint = Forward()("subtype_constraint")
|
||||
string_type = Forward()("string_type")
|
||||
function_decl = Forward()("function_decl")
|
||||
general_list_type = Forward()("general_list_type")
|
||||
supertype_factor = Forward()("supertype_factor")
|
||||
rule_decl = Forward()("rule_decl")
|
||||
precision_spec = Forward()("precision_spec")
|
||||
general_bag_type = Forward()("general_bag_type")
|
||||
qualifiable_factor = Forward()("qualifiable_factor")
|
||||
bound_2 = Forward()("bound_2")
|
||||
instantiable_type = Forward()("instantiable_type")
|
||||
general_set_type = Forward()("general_set_type")
|
||||
supertype_rule = Forward()("supertype_rule")
|
||||
factor = Forward()("factor")
|
||||
list_type = Forward()("list_type")
|
||||
one_of = Forward()("one_of")
|
||||
aggregate_type = Forward()("aggregate_type")
|
||||
entity_body = Forward()("entity_body")
|
||||
generalized_types = Forward()("generalized_types")
|
||||
case_stmt = Forward()("case_stmt")
|
||||
binary_type = Forward()("binary_type")
|
||||
local_decl = Forward()("local_decl")
|
||||
alias_stmt = Forward()("alias_stmt")
|
||||
simple_expression = Forward()("simple_expression")
|
||||
general_array_type = Forward()("general_array_type")
|
||||
interval = Forward()("interval")
|
||||
procedure_head = Forward()("procedure_head")
|
||||
function_decl = Forward()("function_decl")
|
||||
supertype_expression = Forward()("supertype_expression")
|
||||
set_type = Forward()("set_type")
|
||||
primary = Forward()("primary")
|
||||
procedure_call_stmt = Forward()("procedure_call_stmt")
|
||||
simple_types = Forward()("simple_types")
|
||||
query_expression = Forward()("query_expression")
|
||||
index_2 = Forward()("index_2")
|
||||
constant_decl = Forward()("constant_decl")
|
||||
case_action = Forward()("case_action")
|
||||
schema_body = Forward()("schema_body")
|
||||
element = Forward()("element")
|
||||
numeric_expression = Forward()("numeric_expression")
|
||||
aggregate_initializer = Forward()("aggregate_initializer")
|
||||
schema_decl = Forward()("schema_decl")
|
||||
supertype_term = Forward()("supertype_term")
|
||||
algorithm_head = Forward()("algorithm_head")
|
||||
supertype_constraint = Forward()("supertype_constraint")
|
||||
interval_low = Forward()("interval_low")
|
||||
domain_rule = Forward()("domain_rule")
|
||||
rule_decl = Forward()("rule_decl")
|
||||
concrete_types = Forward()("concrete_types")
|
||||
qualifier = Forward()("qualifier")
|
||||
subtype_constraint_body = Forward()("subtype_constraint_body")
|
||||
function_call = Forward()("function_call")
|
||||
bound_spec = Forward()("bound_spec")
|
||||
stmt << (((alias_stmt | assignment_stmt | case_stmt | compound_stmt | escape_stmt | if_stmt | null_stmt | procedure_call_stmt | repeat_stmt | return_stmt | skip_stmt))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="stmt"))
|
||||
general_aggregation_types << (((general_array_type | general_bag_type | general_list_type | general_set_type))).setParseAction(AggregationType)
|
||||
procedure_call_stmt << ((((built_in_procedure | procedure_ref) + actual_parameter_list + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="procedure_call_stmt"))
|
||||
inverse_attr << (((attribute_decl + CaselessLiteral(":") + Optional(((SET | BAG) + Optional(bound_spec) + OF)) + entity_ref + FOR + Optional((entity_ref + CaselessLiteral("."))) + attribute_ref + CaselessLiteral(";")))).setParseAction(InverseAttribute)
|
||||
derived_attr << (((attribute_decl + CaselessLiteral(":") + parameter_type + CaselessLiteral(":=") + expression + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="derived_attr"))
|
||||
width_spec << (((CaselessLiteral("(") + width + CaselessLiteral(")") + Optional(FIXED)))).setParseAction(WidthSpec)
|
||||
actual_parameter_list << (((CaselessLiteral("(") + Optional(parameter) + ZeroOrMore((CaselessLiteral(",") + parameter)) + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="actual_parameter_list"))
|
||||
type_decl << (((TYPE + type_id + CaselessLiteral("=") + underlying_type + CaselessLiteral(";") + Optional(where_clause) + END_TYPE + CaselessLiteral(";")))).setParseAction(TypeDeclaration)
|
||||
selector << (expression)
|
||||
abstract_supertype_declaration << (((ABSTRACT + SUPERTYPE + Optional(subtype_constraint)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="abstract_supertype_declaration"))
|
||||
explicit_attr << (((attribute_decl + ZeroOrMore((CaselessLiteral(",") + attribute_decl)) + CaselessLiteral(":") + Optional(OPTIONAL) + parameter_type + CaselessLiteral(";")))).setParseAction(ExplicitAttribute)
|
||||
aggregation_types << (((array_type | bag_type | list_type | set_type))).setParseAction(AggregationType)
|
||||
domain_rule << (((Optional((rule_label_id + CaselessLiteral(":"))) + expression))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="domain_rule"))
|
||||
entity_constructor << (((entity_ref + CaselessLiteral("(") + Optional((expression + ZeroOrMore((CaselessLiteral(",") + expression)))) + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="entity_constructor"))
|
||||
function_call << ((((built_in_function | function_ref) + actual_parameter_list))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="function_call"))
|
||||
numeric_expression << (simple_expression)
|
||||
general_set_type << (((SET + Optional(bound_spec) + OF + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="general_set_type"))
|
||||
qualifier << (((attribute_qualifier | group_qualifier | index_qualifier))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="qualifier"))
|
||||
formal_parameter << (((parameter_id + ZeroOrMore((CaselessLiteral(",") + parameter_id)) + CaselessLiteral(":") + parameter_type))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="formal_parameter"))
|
||||
index_1 << (index)
|
||||
underlying_type << (((constructed_types | concrete_types))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="underlying_type"))
|
||||
local_variable << (((variable_id + ZeroOrMore((CaselessLiteral(",") + variable_id)) + CaselessLiteral(":") + parameter_type + Optional((CaselessLiteral(":=") + expression)) + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="local_variable"))
|
||||
aggregate_source << (simple_expression)
|
||||
while_control << (((WHILE + logical_expression))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="while_control"))
|
||||
interval_low << (simple_expression)
|
||||
parameter << (expression)
|
||||
precision_spec << (numeric_expression)
|
||||
one_of << (((ONEOF + CaselessLiteral("(") + supertype_expression + ZeroOrMore((CaselessLiteral(",") + supertype_expression)) + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="one_of"))
|
||||
subtype_constraint_body << (((Optional(abstract_supertype) + Optional(total_over) + Optional((supertype_expression + CaselessLiteral(";")))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="subtype_constraint_body"))
|
||||
general_array_type << (((ARRAY + Optional(bound_spec) + OF + Optional(OPTIONAL) + Optional(UNIQUE) + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="general_array_type"))
|
||||
list_type << (((LIST + Optional(bound_spec) + OF + Optional(UNIQUE) + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="list_type"))
|
||||
subtype_constraint_decl << (((subtype_constraint_head + subtype_constraint_body + END_SUBTYPE_CONSTRAINT + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="subtype_constraint_decl"))
|
||||
schema_decl << (((SCHEMA + schema_id + Optional(schema_version_id) + CaselessLiteral(";") + schema_body + END_SCHEMA + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="schema_decl"))
|
||||
algorithm_head << (((ZeroOrMore(declaration) + Optional(constant_decl) + Optional(local_decl)))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="algorithm_head"))
|
||||
query_expression << (((QUERY + CaselessLiteral("(") + variable_id + CaselessLiteral("<*") + aggregate_source + CaselessLiteral("|") + logical_expression + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="query_expression"))
|
||||
primary << (((literal | (qualifiable_factor + ZeroOrMore(qualifier))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="primary"))
|
||||
repeat_control << (((Optional(increment_control) + Optional(while_control) + Optional(until_control)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="repeat_control"))
|
||||
factor << (((simple_factor + Optional((CaselessLiteral("**") + simple_factor))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="factor"))
|
||||
procedure_head << (((PROCEDURE + procedure_id + Optional((CaselessLiteral("(") + Optional(VAR) + formal_parameter + ZeroOrMore((CaselessLiteral(";") + Optional(VAR) + formal_parameter)) + CaselessLiteral(")"))) + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="procedure_head"))
|
||||
aggregate_type << (((AGGREGATE + Optional((CaselessLiteral(":") + type_label)) + OF + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="aggregate_type"))
|
||||
derive_clause = Forward()("derive_clause")
|
||||
supertype_factor << (((supertype_term + ZeroOrMore((AND + supertype_term))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="supertype_factor"))
|
||||
interval_item << (simple_expression)
|
||||
subtype_constraint << (((OF + CaselessLiteral("(") + supertype_expression + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="subtype_constraint"))
|
||||
repeat_stmt << (((REPEAT + repeat_control + CaselessLiteral(";") + stmt + ZeroOrMore(stmt) + END_REPEAT + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="repeat_stmt"))
|
||||
entity_body << (((ZeroOrMore(explicit_attr) + Optional(derive_clause) + Optional(inverse_clause) + Optional(unique_clause) + Optional(where_clause)))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="entity_body"))
|
||||
interval_high << (simple_expression)
|
||||
logical_expression << (expression)
|
||||
simple_expression << (((term + ZeroOrMore((add_like_op + term))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="simple_expression"))
|
||||
subsuper << (((Optional(supertype_constraint) + Optional(subtype_declaration)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="subsuper"))
|
||||
increment << (numeric_expression)
|
||||
remark << (((embedded_remark | tail_remark))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="remark"))
|
||||
simple_factor << (((aggregate_initializer | interval | query_expression | (Optional(unary_op) + ((CaselessLiteral("(") + expression + CaselessLiteral(")")) | primary)) | entity_constructor | enumeration_reference))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="simple_factor"))
|
||||
case_stmt << (((CASE + selector + OF + ZeroOrMore(case_action) + Optional((OTHERWISE + CaselessLiteral(":") + stmt)) + END_CASE + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="case_stmt"))
|
||||
derive_clause << (((DERIVE + derived_attr + ZeroOrMore(derived_attr)))).setParseAction(AttributeList)
|
||||
supertype_constraint << (((abstract_supertype_declaration | abstract_entity_declaration | supertype_rule))).setParseAction(SuperTypeExpression)
|
||||
assignment_stmt << (((general_ref + ZeroOrMore(qualifier) + CaselessLiteral(":=") + expression + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="assignment_stmt"))
|
||||
entity_head << (((ENTITY + entity_id + subsuper + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="entity_head"))
|
||||
set_type << (((SET + Optional(bound_spec) + OF + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="set_type"))
|
||||
instantiable_type << (((concrete_types | entity_ref))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="instantiable_type"))
|
||||
increment_control << (((variable_id + CaselessLiteral(":=") + bound_1 + TO + bound_2 + Optional((BY + increment))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="increment_control"))
|
||||
local_variable << (((variable_id + ZeroOrMore((CaselessLiteral(",") + variable_id)) + CaselessLiteral(":") + parameter_type + Optional((CaselessLiteral(":=") + expression)) + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="local_variable"))
|
||||
until_control << (((UNTIL + logical_expression))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="until_control"))
|
||||
while_control << (((WHILE + logical_expression))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="while_control"))
|
||||
parameter << (expression)
|
||||
width << (numeric_expression)
|
||||
string_type << (((STRING + Optional(width_spec)))).setParseAction(StringType)
|
||||
array_type << (((ARRAY + bound_spec + OF + Optional(OPTIONAL) + Optional(UNIQUE) + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="array_type"))
|
||||
if_stmt << (((IF + logical_expression + THEN + stmt + ZeroOrMore(stmt) + Optional((ELSE + stmt + ZeroOrMore(stmt))) + END_IF + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="if_stmt"))
|
||||
index << (numeric_expression)
|
||||
repetition << (numeric_expression)
|
||||
index_qualifier << (((CaselessLiteral("[") + index_1 + Optional((CaselessLiteral(":") + index_2)) + CaselessLiteral("]")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="index_qualifier"))
|
||||
bound_1 << (numeric_expression)
|
||||
procedure_decl << (((procedure_head + algorithm_head + ZeroOrMore(stmt) + END_PROCEDURE + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="procedure_decl"))
|
||||
entity_constructor << (((entity_ref + CaselessLiteral("(") + Optional((expression + ZeroOrMore((CaselessLiteral(",") + expression)))) + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="entity_constructor"))
|
||||
inverse_clause << (((INVERSE + inverse_attr + ZeroOrMore(inverse_attr)))).setParseAction(AttributeList)
|
||||
function_head << (((FUNCTION + function_id + Optional((CaselessLiteral("(") + formal_parameter + ZeroOrMore((CaselessLiteral(";") + formal_parameter)) + CaselessLiteral(")"))) + CaselessLiteral(":") + parameter_type + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="function_head"))
|
||||
formal_parameter << (((parameter_id + ZeroOrMore((CaselessLiteral(",") + parameter_id)) + CaselessLiteral(":") + parameter_type))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="formal_parameter"))
|
||||
interval_high << (simple_expression)
|
||||
entity_decl << (((entity_head + entity_body + END_ENTITY + CaselessLiteral(";")))).setParseAction(EntityDeclaration)
|
||||
abstract_supertype_declaration << (((ABSTRACT + SUPERTYPE + Optional(subtype_constraint)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="abstract_supertype_declaration"))
|
||||
index_1 << (index)
|
||||
general_aggregation_types << (((general_array_type | general_bag_type | general_list_type | general_set_type))).setParseAction(AggregationType)
|
||||
real_type << (((REAL + Optional((CaselessLiteral("(") + precision_spec + CaselessLiteral(")")))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="real_type"))
|
||||
type_decl << (((TYPE + type_id + CaselessLiteral("=") + underlying_type + CaselessLiteral(";") + Optional(where_clause) + END_TYPE + CaselessLiteral(";")))).setParseAction(TypeDeclaration)
|
||||
stmt << (((alias_stmt | assignment_stmt | case_stmt | compound_stmt | escape_stmt | if_stmt | null_stmt | procedure_call_stmt | repeat_stmt | return_stmt | skip_stmt))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="stmt"))
|
||||
declaration << (((entity_decl | function_decl | procedure_decl | subtype_constraint_decl | type_decl))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="declaration"))
|
||||
binary_type << (((BINARY + Optional(width_spec)))).setParseAction(BinaryType)
|
||||
interval << (((CaselessLiteral("{") + interval_low + interval_op + interval_item + interval_op + interval_high + CaselessLiteral("}")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="interval"))
|
||||
explicit_attr << (((attribute_decl + ZeroOrMore((CaselessLiteral(",") + attribute_decl)) + CaselessLiteral(":") + Optional(OPTIONAL) + parameter_type + CaselessLiteral(";")))).setParseAction(ExplicitAttribute)
|
||||
compound_stmt << (((BEGIN + stmt + ZeroOrMore(stmt) + END + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="compound_stmt"))
|
||||
aggregation_types << (((array_type | bag_type | list_type | set_type))).setParseAction(AggregationType)
|
||||
simple_factor << (((aggregate_initializer | interval | query_expression | (Optional(unary_op) + ((CaselessLiteral("(") + expression + CaselessLiteral(")")) | primary)) | entity_constructor | enumeration_reference))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="simple_factor"))
|
||||
where_clause << (((WHERE + domain_rule + CaselessLiteral(";") + ZeroOrMore((domain_rule + CaselessLiteral(";")))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="where_clause"))
|
||||
entity_head << (((ENTITY + entity_id + subsuper + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="entity_head"))
|
||||
underlying_type << (((constructed_types | concrete_types))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="underlying_type"))
|
||||
subtype_constraint_decl << (((subtype_constraint_head + subtype_constraint_body + END_SUBTYPE_CONSTRAINT + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="subtype_constraint_decl"))
|
||||
logical_expression << (expression)
|
||||
case_label << (expression)
|
||||
expression << (((simple_expression + Optional((rel_op_extended + simple_expression))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="expression"))
|
||||
general_list_type << (((LIST + Optional(bound_spec) + OF + Optional(UNIQUE) + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="general_list_type"))
|
||||
actual_parameter_list << (((CaselessLiteral("(") + Optional(parameter) + ZeroOrMore((CaselessLiteral(",") + parameter)) + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="actual_parameter_list"))
|
||||
width_spec << (((CaselessLiteral("(") + width + CaselessLiteral(")") + Optional(FIXED)))).setParseAction(WidthSpec)
|
||||
selector << (expression)
|
||||
syntax << (((schema_decl + ZeroOrMore(schema_decl)))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="syntax"))
|
||||
aggregate_source << (simple_expression)
|
||||
return_stmt << (((RETURN + Optional((CaselessLiteral("(") + expression + CaselessLiteral(")"))) + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="return_stmt"))
|
||||
embedded_remark << (((CaselessLiteral("(*") + Optional(remark_tag) + ZeroOrMore(((not_paren_star + ZeroOrMore(not_paren_star)) | lparen_then_not_lparen_star | (CaselessLiteral("*") + ZeroOrMore(CaselessLiteral("*"))) | not_rparen_star_then_rparen | embedded_remark)) + CaselessLiteral("*)")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="embedded_remark"))
|
||||
parameter_type << (((generalized_types | simple_types | named_types))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="parameter_type"))
|
||||
term << (((factor + ZeroOrMore((multiplication_like_op + factor))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="term"))
|
||||
index << (numeric_expression)
|
||||
expression << (((simple_expression + Optional((rel_op_extended + simple_expression))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="expression"))
|
||||
derived_attr << (((attribute_decl + CaselessLiteral(":") + parameter_type + CaselessLiteral(":=") + expression + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="derived_attr"))
|
||||
repeat_control << (((Optional(increment_control) + Optional(while_control) + Optional(until_control)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="repeat_control"))
|
||||
assignment_stmt << (((general_ref + ZeroOrMore(qualifier) + CaselessLiteral(":=") + expression + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="assignment_stmt"))
|
||||
bag_type << (((BAG + Optional(bound_spec) + OF + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="bag_type"))
|
||||
schema_body << (((ZeroOrMore(interface_specification) + Optional(constant_decl) + ZeroOrMore((declaration | rule_decl))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="schema_body"))
|
||||
until_control << (((UNTIL + logical_expression))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="until_control"))
|
||||
simple_types << (((binary_type | boolean_type | integer_type | logical_type | number_type | real_type | string_type))).setParseAction(SimpleType)
|
||||
subsuper << (((Optional(supertype_constraint) + Optional(subtype_declaration)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="subsuper"))
|
||||
entity_decl << (((entity_head + entity_body + END_ENTITY + CaselessLiteral(";")))).setParseAction(EntityDeclaration)
|
||||
concrete_types << (((aggregation_types | simple_types | type_ref))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="concrete_types"))
|
||||
element << (((expression + Optional((CaselessLiteral(":") + repetition))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="element"))
|
||||
general_bag_type << (((BAG + Optional(bound_spec) + OF + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="general_bag_type"))
|
||||
interval_item << (simple_expression)
|
||||
inverse_attr << (((attribute_decl + CaselessLiteral(":") + Optional(((SET | BAG) + Optional(bound_spec) + OF)) + entity_ref + FOR + Optional((entity_ref + CaselessLiteral("."))) + attribute_ref + CaselessLiteral(";")))).setParseAction(InverseAttribute)
|
||||
constant_body << (((constant_id + CaselessLiteral(":") + instantiable_type + CaselessLiteral(":=") + expression + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="constant_body"))
|
||||
increment << (numeric_expression)
|
||||
case_label << (expression)
|
||||
case_action << (((case_label + ZeroOrMore((CaselessLiteral(",") + case_label)) + CaselessLiteral(":") + stmt))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="case_action"))
|
||||
width << (numeric_expression)
|
||||
procedure_decl << (((procedure_head + algorithm_head + ZeroOrMore(stmt) + END_PROCEDURE + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="procedure_decl"))
|
||||
increment_control << (((variable_id + CaselessLiteral(":=") + bound_1 + TO + bound_2 + Optional((BY + increment))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="increment_control"))
|
||||
index_qualifier << (((CaselessLiteral("[") + index_1 + Optional((CaselessLiteral(":") + index_2)) + CaselessLiteral("]")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="index_qualifier"))
|
||||
constant_decl << (((CONSTANT + constant_body + ZeroOrMore(constant_body) + END_CONSTANT + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="constant_decl"))
|
||||
supertype_rule << (((SUPERTYPE + subtype_constraint))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="supertype_rule"))
|
||||
syntax << (((schema_decl + ZeroOrMore(schema_decl)))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="syntax"))
|
||||
function_head << (((FUNCTION + function_id + Optional((CaselessLiteral("(") + formal_parameter + ZeroOrMore((CaselessLiteral(";") + formal_parameter)) + CaselessLiteral(")"))) + CaselessLiteral(":") + parameter_type + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="function_head"))
|
||||
repetition << (numeric_expression)
|
||||
if_stmt << (((IF + logical_expression + THEN + stmt + ZeroOrMore(stmt) + Optional((ELSE + stmt + ZeroOrMore(stmt))) + END_IF + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="if_stmt"))
|
||||
supertype_expression << (((supertype_factor + ZeroOrMore((ANDOR + supertype_factor))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="supertype_expression"))
|
||||
inverse_clause << (((INVERSE + inverse_attr + ZeroOrMore(inverse_attr)))).setParseAction(AttributeList)
|
||||
aggregate_initializer << (((CaselessLiteral("[") + Optional((element + ZeroOrMore((CaselessLiteral(",") + element)))) + CaselessLiteral("]")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="aggregate_initializer"))
|
||||
return_stmt << (((RETURN + Optional((CaselessLiteral("(") + expression + CaselessLiteral(")"))) + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="return_stmt"))
|
||||
generalized_types << (((aggregate_type | general_aggregation_types | generic_entity_type | generic_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="generalized_types"))
|
||||
bound_2 << (numeric_expression)
|
||||
real_type << (((REAL + Optional((CaselessLiteral("(") + precision_spec + CaselessLiteral(")")))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="real_type"))
|
||||
index_2 << (index)
|
||||
array_type << (((ARRAY + bound_spec + OF + Optional(OPTIONAL) + Optional(UNIQUE) + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="array_type"))
|
||||
local_decl << (((LOCAL + local_variable + ZeroOrMore(local_variable) + END_LOCAL + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="local_decl"))
|
||||
supertype_term << (((one_of | (CaselessLiteral("(") + supertype_expression + CaselessLiteral(")")) | entity_ref))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="supertype_term"))
|
||||
where_clause << (((WHERE + domain_rule + CaselessLiteral(";") + ZeroOrMore((domain_rule + CaselessLiteral(";")))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="where_clause"))
|
||||
embedded_remark << (((CaselessLiteral("(*") + Optional(remark_tag) + ZeroOrMore(((not_paren_star + ZeroOrMore(not_paren_star)) | lparen_then_not_lparen_star | (CaselessLiteral("*") + ZeroOrMore(CaselessLiteral("*"))) | not_rparen_star_then_rparen | embedded_remark)) + CaselessLiteral("*)")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="embedded_remark"))
|
||||
compound_stmt << (((BEGIN + stmt + ZeroOrMore(stmt) + END + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="compound_stmt"))
|
||||
bound_1 << (numeric_expression)
|
||||
alias_stmt << (((ALIAS + variable_id + FOR + general_ref + ZeroOrMore(qualifier) + CaselessLiteral(";") + stmt + ZeroOrMore(stmt) + END_ALIAS + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="alias_stmt"))
|
||||
subtype_constraint << (((OF + CaselessLiteral("(") + supertype_expression + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="subtype_constraint"))
|
||||
string_type << (((STRING + Optional(width_spec)))).setParseAction(StringType)
|
||||
function_decl << (((function_head + algorithm_head + stmt + ZeroOrMore(stmt) + END_FUNCTION + CaselessLiteral(";")))).setParseAction(FunctionDeclaration)
|
||||
general_list_type << (((LIST + Optional(bound_spec) + OF + Optional(UNIQUE) + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="general_list_type"))
|
||||
supertype_factor << (((supertype_term + ZeroOrMore((AND + supertype_term))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="supertype_factor"))
|
||||
rule_decl << (((rule_head + algorithm_head + ZeroOrMore(stmt) + where_clause + END_RULE + CaselessLiteral(";")))).setParseAction(RuleDeclaration)
|
||||
precision_spec << (numeric_expression)
|
||||
general_bag_type << (((BAG + Optional(bound_spec) + OF + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="general_bag_type"))
|
||||
qualifiable_factor << (((function_call | attribute_ref | constant_factor | general_ref | population))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="qualifiable_factor"))
|
||||
bound_2 << (numeric_expression)
|
||||
instantiable_type << (((concrete_types | entity_ref))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="instantiable_type"))
|
||||
general_set_type << (((SET + Optional(bound_spec) + OF + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="general_set_type"))
|
||||
supertype_rule << (((SUPERTYPE + subtype_constraint))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="supertype_rule"))
|
||||
factor << (((simple_factor + Optional((CaselessLiteral("**") + simple_factor))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="factor"))
|
||||
list_type << (((LIST + Optional(bound_spec) + OF + Optional(UNIQUE) + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="list_type"))
|
||||
one_of << (((ONEOF + CaselessLiteral("(") + supertype_expression + ZeroOrMore((CaselessLiteral(",") + supertype_expression)) + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="one_of"))
|
||||
aggregate_type << (((AGGREGATE + Optional((CaselessLiteral(":") + type_label)) + OF + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="aggregate_type"))
|
||||
entity_body << (((ZeroOrMore(explicit_attr) + Optional(derive_clause) + Optional(inverse_clause) + Optional(unique_clause) + Optional(where_clause)))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="entity_body"))
|
||||
generalized_types << (((aggregate_type | general_aggregation_types | generic_entity_type | generic_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="generalized_types"))
|
||||
case_stmt << (((CASE + selector + OF + ZeroOrMore(case_action) + Optional((OTHERWISE + CaselessLiteral(":") + stmt)) + END_CASE + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="case_stmt"))
|
||||
binary_type << (((BINARY + Optional(width_spec)))).setParseAction(BinaryType)
|
||||
local_decl << (((LOCAL + local_variable + ZeroOrMore(local_variable) + END_LOCAL + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="local_decl"))
|
||||
alias_stmt << (((ALIAS + variable_id + FOR + general_ref + ZeroOrMore(qualifier) + CaselessLiteral(";") + stmt + ZeroOrMore(stmt) + END_ALIAS + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="alias_stmt"))
|
||||
simple_expression << (((term + ZeroOrMore((add_like_op + term))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="simple_expression"))
|
||||
general_array_type << (((ARRAY + Optional(bound_spec) + OF + Optional(OPTIONAL) + Optional(UNIQUE) + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="general_array_type"))
|
||||
interval << (((CaselessLiteral("{") + interval_low + interval_op + interval_item + interval_op + interval_high + CaselessLiteral("}")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="interval"))
|
||||
procedure_head << (((PROCEDURE + procedure_id + Optional((CaselessLiteral("(") + Optional(VAR) + formal_parameter + ZeroOrMore((CaselessLiteral(";") + Optional(VAR) + formal_parameter)) + CaselessLiteral(")"))) + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="procedure_head"))
|
||||
function_decl << (((function_head + algorithm_head + stmt + ZeroOrMore(stmt) + END_FUNCTION + CaselessLiteral(";")))).setParseAction(FunctionDeclaration)
|
||||
supertype_expression << (((supertype_factor + ZeroOrMore((ANDOR + supertype_factor))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="supertype_expression"))
|
||||
set_type << (((SET + Optional(bound_spec) + OF + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="set_type"))
|
||||
primary << (((literal | (qualifiable_factor + ZeroOrMore(qualifier))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="primary"))
|
||||
procedure_call_stmt << ((((built_in_procedure | procedure_ref) + actual_parameter_list + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="procedure_call_stmt"))
|
||||
simple_types << (((binary_type | boolean_type | integer_type | logical_type | number_type | real_type | string_type))).setParseAction(SimpleType)
|
||||
query_expression << (((QUERY + CaselessLiteral("(") + variable_id + CaselessLiteral("<*") + aggregate_source + CaselessLiteral("|") + logical_expression + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="query_expression"))
|
||||
index_2 << (index)
|
||||
constant_decl << (((CONSTANT + constant_body + ZeroOrMore(constant_body) + END_CONSTANT + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="constant_decl"))
|
||||
case_action << (((case_label + ZeroOrMore((CaselessLiteral(",") + case_label)) + CaselessLiteral(":") + stmt))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="case_action"))
|
||||
schema_body << (((ZeroOrMore(interface_specification) + Optional(constant_decl) + ZeroOrMore((declaration | rule_decl))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="schema_body"))
|
||||
element << (((expression + Optional((CaselessLiteral(":") + repetition))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="element"))
|
||||
numeric_expression << (simple_expression)
|
||||
aggregate_initializer << (((CaselessLiteral("[") + Optional((element + ZeroOrMore((CaselessLiteral(",") + element)))) + CaselessLiteral("]")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="aggregate_initializer"))
|
||||
schema_decl << (((SCHEMA + schema_id + Optional(schema_version_id) + CaselessLiteral(";") + schema_body + END_SCHEMA + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="schema_decl"))
|
||||
supertype_term << (((one_of | (CaselessLiteral("(") + supertype_expression + CaselessLiteral(")")) | entity_ref))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="supertype_term"))
|
||||
algorithm_head << (((ZeroOrMore(declaration) + Optional(constant_decl) + Optional(local_decl)))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="algorithm_head"))
|
||||
supertype_constraint << (((abstract_supertype_declaration | abstract_entity_declaration | supertype_rule))).setParseAction(SuperTypeExpression)
|
||||
interval_low << (simple_expression)
|
||||
domain_rule << (((Optional((rule_label_id + CaselessLiteral(":"))) + expression))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="domain_rule"))
|
||||
rule_decl << (((rule_head + algorithm_head + ZeroOrMore(stmt) + where_clause + END_RULE + CaselessLiteral(";")))).setParseAction(RuleDeclaration)
|
||||
concrete_types << (((aggregation_types | simple_types | type_ref))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="concrete_types"))
|
||||
qualifier << (((attribute_qualifier | group_qualifier | index_qualifier))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="qualifier"))
|
||||
subtype_constraint_body << (((Optional(abstract_supertype) + Optional(total_over) + Optional((supertype_expression + CaselessLiteral(";")))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="subtype_constraint_body"))
|
||||
function_call << ((((built_in_function | function_ref) + actual_parameter_list))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="function_call"))
|
||||
bound_spec << (((CaselessLiteral("[") + bound_1 + CaselessLiteral(":") + bound_2 + CaselessLiteral("]")))).setParseAction(BoundSpecification)
|
||||
derive_clause << (((DERIVE + derived_attr + ZeroOrMore(derived_attr)))).setParseAction(AttributeList)
|
||||
|
||||
syntax.ignore("--" + restOfLine)
|
||||
syntax.ignore(Regex(r"\((?:\*(?:[^*]*\*+)+?\))"))
|
||||
|
||||
@@ -155,6 +155,7 @@ class Header(codegen.Base):
|
||||
tt = mapping.schema.entities[tt.supertypes[0]]
|
||||
|
||||
supertypes = list(type.supertypes) if len(type.supertypes) else ["IfcUtil::IfcBaseEntity"]
|
||||
direct_superclass = supertypes[0]
|
||||
supertypes.extend(get_select_super_types(name, bases=all_supertypes))
|
||||
supertypes = list(map(case_normalize, supertypes))
|
||||
superclass = create_supertype_statement(supertypes)
|
||||
|
||||
@@ -115,8 +115,8 @@ class Implementation(codegen.Base):
|
||||
null_check = ""
|
||||
if arg["is_optional"]:
|
||||
attr_check = (
|
||||
"if(!data_->getArgument(%d) || data_->getArgument(%d)->isNull()) { return %%s; }"
|
||||
% (arg["index"] - 1, arg["index"] - 1)
|
||||
"if(data_.get_attribute_value(%d).isNull()) { return %%s; }"
|
||||
% (arg["index"] - 1,)
|
||||
)
|
||||
if "boost::optional" in arg["full_type"]:
|
||||
null_check = attr_check % "boost::none"
|
||||
@@ -236,11 +236,17 @@ class Implementation(codegen.Base):
|
||||
]
|
||||
|
||||
superclass = (
|
||||
"%s((IfcEntityInstanceData*)0)" % type.supertypes[0]
|
||||
"%s(std::move(e))" % type.supertypes[0]
|
||||
if len(type.supertypes) == 1
|
||||
else "IfcUtil::IfcBaseEntity()"
|
||||
else "IfcUtil::IfcBaseEntity(std::move(e))"
|
||||
)
|
||||
|
||||
superclass_num_attrs = (
|
||||
"%s(IfcEntityInstanceData(storage_t(%%d)))" % type.supertypes[0]
|
||||
if len(type.supertypes) == 1
|
||||
else "IfcUtil::IfcBaseEntity(IfcEntityInstanceData(storage_t(%d)))"
|
||||
) % len(constructor_arguments)
|
||||
|
||||
write(
|
||||
templates.entity_implementation,
|
||||
name=name,
|
||||
@@ -250,6 +256,7 @@ class Implementation(codegen.Base):
|
||||
attributes=nl(catnl(attributes)),
|
||||
inverse=nl(catnl(inverse)),
|
||||
superclass=superclass,
|
||||
superclass_num_attrs=superclass_num_attrs,
|
||||
schema_name=schema_name,
|
||||
schema_name_upper=schema_name_upper,
|
||||
index_in_schema=self.names.index(str(name)),
|
||||
@@ -302,7 +309,7 @@ class Implementation(codegen.Base):
|
||||
for class_name, type in mapping.schema.simpletypes.items():
|
||||
type_str = mapping.make_type_string(mapping.flatten_type_string(type))
|
||||
attr_type = mapping.make_argument_type(type)
|
||||
superclass = mapping.simple_type_parent(class_name)
|
||||
superclass = mapping.simple_type_parent(class_name) or "IfcUtil::IfcBaseType"
|
||||
|
||||
simpletype_impl_is = (
|
||||
templates.simpletype_impl_is_with_supertype
|
||||
@@ -310,7 +317,7 @@ class Implementation(codegen.Base):
|
||||
else templates.simpletype_impl_is_without_supertype
|
||||
)
|
||||
|
||||
constructor = templates.constructor_single_initlist if superclass else templates.constructor
|
||||
constructor = templates.constructor_single_initlist# if superclass else templates.constructor
|
||||
|
||||
simpletype_impl_cast = (
|
||||
templates.simpletype_impl_cast_templated
|
||||
@@ -337,9 +344,10 @@ class Implementation(codegen.Base):
|
||||
map(
|
||||
compose,
|
||||
map(
|
||||
lambda x: (class_name, attr_type, superclass, "(IfcEntityInstanceData*)0") + x,
|
||||
lambda x: (class_name, attr_type, superclass) + x,
|
||||
(
|
||||
(
|
||||
"",
|
||||
"Class",
|
||||
templates.function,
|
||||
"const IfcParse::type_declaration&",
|
||||
@@ -347,6 +355,7 @@ class Implementation(codegen.Base):
|
||||
templates.simpletype_impl_class,
|
||||
),
|
||||
(
|
||||
"",
|
||||
"declaration",
|
||||
templates.const_function,
|
||||
"const IfcParse::type_declaration&",
|
||||
@@ -354,14 +363,16 @@ class Implementation(codegen.Base):
|
||||
templates.simpletype_impl_declaration,
|
||||
),
|
||||
(
|
||||
"std::move(e)",
|
||||
"",
|
||||
constructor,
|
||||
"",
|
||||
("IfcEntityInstanceData* e",),
|
||||
templates.simpletype_impl_explicit_constructor,
|
||||
("IfcEntityInstanceData&& e",),
|
||||
"",
|
||||
),
|
||||
("", constructor, "", ("%s v" % type_str,), simpletype_impl_constructor),
|
||||
("", templates.cast_function, type_str, (), simpletype_impl_cast),
|
||||
("", "", 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),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -330,13 +330,13 @@ class EarlyBoundCodeWriter:
|
||||
name = idx_name[1]
|
||||
return name in can_be_instantiated_set
|
||||
|
||||
instance_mapping = """switch(data->type()->index_in_schema()) {
|
||||
instance_mapping = """switch(decl->index_in_schema()) {
|
||||
%s
|
||||
default: throw IfcParse::IfcException(data->type()->name() + " cannot be instantiated");
|
||||
default: throw IfcParse::IfcException(decl->name() + " cannot be instantiated");
|
||||
}
|
||||
""" % "\n ".join(
|
||||
map(
|
||||
lambda tup: ("case %%d: return new ::%s::%%s(data);" % schema_name_title) % tup,
|
||||
lambda tup: ("case %%d: return new ::%s::%%s(std::move(data));" % schema_name_title) % tup,
|
||||
filter(can_be_instantiated, enumerate(self.names)),
|
||||
)
|
||||
)
|
||||
@@ -344,7 +344,7 @@ class EarlyBoundCodeWriter:
|
||||
self.statements[self.statements.index("{factory_placeholder}")] = (
|
||||
"""
|
||||
class %(schema_name)s_instance_factory : public IfcParse::instance_factory {
|
||||
virtual IfcUtil::IfcBaseClass* operator()(IfcEntityInstanceData* data) const {
|
||||
virtual IfcUtil::IfcBaseClass* operator()(const IfcParse::declaration* decl, IfcEntityInstanceData&& data) const {
|
||||
%(instance_mapping)s
|
||||
}
|
||||
};
|
||||
|
||||
@@ -71,14 +71,13 @@ implementation = """
|
||||
#include "../ifcparse/%(schema_name)s.h"
|
||||
#include "../ifcparse/IfcSchema.h"
|
||||
#include "../ifcparse/IfcException.h"
|
||||
#include "../ifcparse/IfcWrite.h"
|
||||
#include "../ifcparse/IfcFile.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
const char* const %(schema_name)s::Identifier = "%(schema_name_upper)s";
|
||||
|
||||
using namespace IfcParse;
|
||||
using namespace IfcWrite;
|
||||
|
||||
// External definitions
|
||||
%(external_definitions)s
|
||||
@@ -113,7 +112,7 @@ class IFC_PARSE_API %(name)s : %(superclass)s {
|
||||
public:
|
||||
virtual const IfcParse::type_declaration& declaration() const;
|
||||
static const IfcParse::type_declaration& Class();
|
||||
explicit %(name)s (IfcEntityInstanceData* e);
|
||||
explicit %(name)s (IfcEntityInstanceData&& e);
|
||||
%(name)s (%(type)s v);
|
||||
operator %(type)s() const;
|
||||
};
|
||||
@@ -121,19 +120,19 @@ public:
|
||||
|
||||
simpletype_impl_comment = "// Function implementations for %(name)s"
|
||||
simpletype_impl_argument_type = 'if (i == 0) { return %(attr_type)s; } else { throw IfcParse::IfcAttributeOutOfRangeException("Argument index out of range"); }'
|
||||
simpletype_impl_argument = "return data_->getArgument(i);"
|
||||
simpletype_impl_argument = "return data_.get_attribute_value(i);"
|
||||
simpletype_impl_is_with_supertype = "return v == %(class_name)s_type || %(superclass)s::is(v);"
|
||||
simpletype_impl_is_without_supertype = "return v == %(class_name)s_type;"
|
||||
simpletype_impl_type = "return *((IfcParse::type_declaration*)%(schema_name_upper)s_types[%(index_in_schema)d]);"
|
||||
simpletype_impl_class = "return *((IfcParse::type_declaration*)%(schema_name_upper)s_types[%(index_in_schema)d]);"
|
||||
simpletype_impl_explicit_constructor = "data_ = e;"
|
||||
simpletype_impl_constructor = (
|
||||
"data_ = new IfcEntityInstanceData(%(schema_name_upper)s_types[%(index_in_schema)d]); set_value(0, v);"
|
||||
"data_ = new IfcEntityInstanceData(%(schema_name_upper)s_types[%(index_in_schema)d]); set_attribute_value(0, v);"
|
||||
)
|
||||
simpletype_impl_constructor_templated = "data_ = new IfcEntityInstanceData(%(schema_name_upper)s_types[%(index_in_schema)d]); set_value(0, v->generalize());"
|
||||
simpletype_impl_cast = "return *data_->getArgument(0);"
|
||||
simpletype_impl_constructor_templated = "data_ = new IfcEntityInstanceData(%(schema_name_upper)s_types[%(index_in_schema)d]); set_attribute_value(0, v->generalize());"
|
||||
simpletype_impl_cast = "return data_.get_attribute_value(0);"
|
||||
simpletype_impl_cast_templated = (
|
||||
"aggregate_of_instance::ptr es = *data_->getArgument(0); return es->as< %(underlying_type)s >();"
|
||||
"aggregate_of_instance::ptr es = data_.get_attribute_value(0); return es->as< %(underlying_type)s >();"
|
||||
)
|
||||
simpletype_impl_declaration = "return *((IfcParse::type_declaration*)%(schema_name_upper)s_types[%(index_in_schema)d]);"
|
||||
|
||||
@@ -154,7 +153,7 @@ public:
|
||||
|
||||
virtual const IfcParse::enumeration_type& declaration() const;
|
||||
static const IfcParse::enumeration_type& Class();
|
||||
%(name)s (IfcEntityInstanceData* e);
|
||||
%(name)s (IfcEntityInstanceData&& e);
|
||||
%(name)s (Value v);
|
||||
%(name)s (const std::string& v);
|
||||
operator Value() const;
|
||||
@@ -166,7 +165,7 @@ class IFC_PARSE_API %(name)s : %(superclass)s {
|
||||
public:
|
||||
%(attributes)s %(inverse)s virtual const IfcParse::entity& declaration() const;
|
||||
static const IfcParse::entity& Class();
|
||||
%(name)s (IfcEntityInstanceData* e);
|
||||
%(name)s (IfcEntityInstanceData&& e);
|
||||
%(name)s (%(constructor_arguments)s);
|
||||
typedef aggregate_of< %(name)s > list;
|
||||
};
|
||||
@@ -180,18 +179,16 @@ enumeration_function = """
|
||||
const IfcParse::enumeration_type& %(schema_name)s::%(name)s::declaration() const { return *((IfcParse::enumeration_type*)%(schema_name_upper)s_types[%(index_in_schema)d]); }
|
||||
const IfcParse::enumeration_type& %(schema_name)s::%(name)s::Class() { return *((IfcParse::enumeration_type*)%(schema_name_upper)s_types[%(index_in_schema)d]); }
|
||||
|
||||
%(schema_name)s::%(name)s::%(name)s(IfcEntityInstanceData* e) {
|
||||
data_ = e;
|
||||
}
|
||||
%(schema_name)s::%(name)s::%(name)s(IfcEntityInstanceData&& e)
|
||||
: IfcBaseType(std::move(e))
|
||||
{}
|
||||
|
||||
%(schema_name)s::%(name)s::%(name)s(Value v) {
|
||||
data_ = new IfcEntityInstanceData(%(schema_name_upper)s_types[%(index_in_schema)d]);
|
||||
set_value(0, IfcWrite::IfcWriteArgument::EnumerationReference(v,ToString(v)));
|
||||
set_attribute_value(0, EnumerationReference(&declaration(), static_cast<size_t>(v)));
|
||||
}
|
||||
|
||||
%(schema_name)s::%(name)s::%(name)s(const std::string& v) {
|
||||
data_ = new IfcEntityInstanceData(%(schema_name_upper)s_types[%(index_in_schema)d]);
|
||||
set_value(0, IfcWrite::IfcWriteArgument::EnumerationReference(FromString(v),ToString(FromString(v))));
|
||||
set_attribute_value(0, EnumerationReference(&declaration(), declaration().lookup_enum_offset(v)));
|
||||
}
|
||||
|
||||
const char* %(schema_name)s::%(name)s::ToString(Value v) {
|
||||
@@ -203,7 +200,7 @@ const char* %(schema_name)s::%(name)s::ToString(Value v) {
|
||||
}
|
||||
|
||||
%(schema_name)s::%(name)s::operator %(schema_name)s::%(name)s::Value() const {
|
||||
return FromString((std::string) *data_->getArgument(0));
|
||||
return (%(schema_name)s::%(name)s::Value) data_.storage_.get<EnumerationReference>(0).index();
|
||||
}
|
||||
"""
|
||||
|
||||
@@ -212,10 +209,13 @@ entity_implementation = """// Function implementations for %(name)s
|
||||
%(inverse)s
|
||||
const IfcParse::entity& %(schema_name)s::%(name)s::declaration() const { return *((IfcParse::entity*)%(schema_name_upper)s_types[%(index_in_schema)d]); }
|
||||
const IfcParse::entity& %(schema_name)s::%(name)s::Class() { return *((IfcParse::entity*)%(schema_name_upper)s_types[%(index_in_schema)d]); }
|
||||
%(schema_name)s::%(name)s::%(name)s(IfcEntityInstanceData* e) : %(superclass)s { data_ = e; }
|
||||
%(schema_name)s::%(name)s::%(name)s(%(constructor_arguments)s) : %(superclass)s {data_ = new IfcEntityInstanceData(%(schema_name_upper)s_types[%(index_in_schema)d]); %(constructor_implementation)s }
|
||||
%(schema_name)s::%(name)s::%(name)s(IfcEntityInstanceData&& e) : %(superclass)s { }
|
||||
%(schema_name)s::%(name)s::%(name)s(%(constructor_arguments)s) : %(superclass_num_attrs)s { %(constructor_implementation)s }
|
||||
"""
|
||||
|
||||
# data_ = e;
|
||||
# data_ = new IfcEntityInstanceData(%(schema_name_upper)s_types[%(index_in_schema)d]);
|
||||
|
||||
optional_attribute_description = "/// Whether the optional attribute %s is defined for this %s"
|
||||
|
||||
function = "%(return_type)s %(schema_name)s::%(class_name)s::%(name)s(%(arguments)s) { %(body)s }"
|
||||
@@ -241,41 +241,41 @@ parent_type_stmt = " if(v==%(name)s%(padding)s) { return %(parent)s; }"
|
||||
|
||||
parent_type_test = " || %s::is(v)"
|
||||
|
||||
optional_attr_stmt = "return !data_->getArgument(%(index)d)->isNull();"
|
||||
optional_attr_stmt = "return !data_.get_attribute_value(%(index)d).isNull();"
|
||||
|
||||
get_attr_stmt = "%(null_check)s %(non_optional_type)s v = *data_->getArgument(%(index)d); return v;"
|
||||
get_attr_stmt_enum = "%(null_check)s return %(non_optional_type)s::FromString(*data_->getArgument(%(index)d));"
|
||||
get_attr_stmt_entity = "%(null_check)s return ((IfcUtil::IfcBaseClass*)(*data_->getArgument(%(index)d)))->as<%(non_optional_type_no_pointer)s>(true);"
|
||||
get_attr_stmt_array = "%(null_check)s aggregate_of_instance::ptr es = *data_->getArgument(%(index)d); return es->as< %(list_instance_type)s >();"
|
||||
get_attr_stmt_nested_array = "%(null_check)s aggregate_of_aggregate_of_instance::ptr es = *data_->getArgument(%(index)d); return es->as< %(list_instance_type)s >();"
|
||||
get_attr_stmt = "%(null_check)s %(non_optional_type)s v = data_.get_attribute_value(%(index)d); return v;"
|
||||
get_attr_stmt_enum = "%(null_check)s return %(non_optional_type)s::FromString(data_.get_attribute_value(%(index)d));"
|
||||
get_attr_stmt_entity = "%(null_check)s return ((IfcUtil::IfcBaseClass*)(data_.get_attribute_value(%(index)d)))->as<%(non_optional_type_no_pointer)s>(true);"
|
||||
get_attr_stmt_array = "%(null_check)s aggregate_of_instance::ptr es = data_.get_attribute_value(%(index)d); return es->as< %(list_instance_type)s >();"
|
||||
get_attr_stmt_nested_array = "%(null_check)s aggregate_of_aggregate_of_instance::ptr es = data_.get_attribute_value(%(index)d); return es->as< %(list_instance_type)s >();"
|
||||
|
||||
get_inverse = "return data_->getInverse(%(schema_name_upper)s_types[%(type_index)d], %(index)d)->as<%(type)s>();"
|
||||
get_inverse = "if (!file_) { return nullptr; } return file_->getInverse(id_, %(schema_name_upper)s_types[%(type_index)d], %(index)d)->as<%(type)s>();"
|
||||
|
||||
set_attr_stmt = (
|
||||
"%(check_optional_set_begin)sset_value(%(index)d, %(star_if_optional)sv);%(check_optional_set_else)sunset_value(%(index)d);%(check_optional_set_end)s"
|
||||
"%(check_optional_set_begin)sset_attribute_value(%(index)d, %(star_if_optional)sv);%(check_optional_set_else)sunset_attribute_value(%(index)d);%(check_optional_set_end)s"
|
||||
)
|
||||
set_attr_instance = (
|
||||
"%(check_optional_set_begin)sset_value(%(index)d, v->as<IfcUtil::IfcBaseClass>());%(check_optional_set_else)sunset_value(%(index)d);%(check_optional_set_end)s"
|
||||
"%(check_optional_set_begin)sset_attribute_value(%(index)d, v->as<IfcUtil::IfcBaseClass>());%(check_optional_set_else)sunset_attribute_value(%(index)d);%(check_optional_set_end)s"
|
||||
)
|
||||
set_attr_stmt_enum = "%(check_optional_set_begin)sset_value(%(index)d, IfcWrite::IfcWriteArgument::EnumerationReference(%(star_if_optional)sv,%(non_optional_type)s::ToString(%(star_if_optional)sv)));%(check_optional_set_else)sunset_value(%(index)d);%(check_optional_set_end)s"
|
||||
set_attr_stmt_enum = "%(check_optional_set_begin)sset_attribute_value(%(index)d, EnumerationReference(&%(non_optional_type)s::Class(), (size_t) %(star_if_optional)sv));%(check_optional_set_else)sunset_attribute_value(%(index)d);%(check_optional_set_end)s"
|
||||
set_attr_stmt_array = (
|
||||
"%(check_optional_set_begin)sset_value(%(index)d, (%(star_if_optional)sv)->generalize());%(check_optional_set_else)sunset_value(%(index)d);%(check_optional_set_end)s"
|
||||
"%(check_optional_set_begin)sset_attribute_value(%(index)d, (%(star_if_optional)sv)->generalize());%(check_optional_set_else)sunset_attribute_value(%(index)d);%(check_optional_set_end)s"
|
||||
)
|
||||
|
||||
constructor_stmt = (
|
||||
"set_value(%(index)d, (%(name)s));"
|
||||
"set_attribute_value(%(index)d, (%(name)s));"
|
||||
)
|
||||
constructor_stmt_enum = (
|
||||
"set_value(%(index)d, (IfcWrite::IfcWriteArgument::EnumerationReference(%(name)s,%(type)s::ToString(%(name)s))));"
|
||||
"set_attribute_value(%(index)d, (EnumerationReference(&%(type)s::Class(),(size_t)%(name)s)));"
|
||||
)
|
||||
constructor_stmt_array = (
|
||||
"set_value(%(index)d, (%(name)s)->generalize());"
|
||||
"set_attribute_value(%(index)d, (%(name)s)->generalize());"
|
||||
)
|
||||
constructor_stmt_derived = (
|
||||
""
|
||||
)
|
||||
constructor_stmt_instance = (
|
||||
"set_value(%(index)d, %(name)s ? %(name)s->as<IfcUtil::IfcBaseClass>() : (IfcUtil::IfcBaseClass*) nullptr);"
|
||||
"set_attribute_value(%(index)d, %(name)s ? %(name)s->as<IfcUtil::IfcBaseClass>() : (IfcUtil::IfcBaseClass*) nullptr);"
|
||||
)
|
||||
|
||||
constructor_stmt_optional = " if (%(name)s) {%(stmt)s }"
|
||||
|
||||
@@ -256,11 +256,12 @@ def assert_valid(
|
||||
return True
|
||||
|
||||
|
||||
def log_internal_cpp_errors(filename: str, logger: Logger) -> None:
|
||||
def log_internal_cpp_errors(f: ifcopenshell.file, filename: str, logger: Logger) -> None:
|
||||
import re
|
||||
import bisect
|
||||
|
||||
chr_offset_re = re.compile(r"at offset (\d+)\s*")
|
||||
for_instance_re = re.compile(r"\s*for instance #(\d+)\s*")
|
||||
|
||||
log = ifcopenshell.get_log()
|
||||
msgs = list(map(json.loads, filter(None, log.split("\n"))))
|
||||
@@ -286,6 +287,24 @@ def log_internal_cpp_errors(filename: str, logger: Logger) -> None:
|
||||
else:
|
||||
logger.error("For instance:\n %s\n%s", line, m)
|
||||
|
||||
instance_messages = [for_instance_re.findall(m["message"]) for m in msgs]
|
||||
if instance_messages:
|
||||
for instid, msg in zip(instance_messages, msgs):
|
||||
if instid:
|
||||
m = for_instance_re.sub("", msg["message"])
|
||||
try:
|
||||
inst = f[int(instid[0])]
|
||||
except:
|
||||
inst = None
|
||||
if hasattr(logger, "set_state"):
|
||||
logger.set_state("instance", inst)
|
||||
logger.set_state("attribute", None)
|
||||
logger.error(m)
|
||||
elif inst:
|
||||
logger.error("For instance:\n %s\n%s", inst, m)
|
||||
else:
|
||||
logger.error(m)
|
||||
|
||||
|
||||
entity_attribute_map: dict[tuple[str, str], tuple[entity_type, tuple[attribute]]] = {}
|
||||
|
||||
@@ -368,7 +387,7 @@ def validate(f: Union[ifcopenshell.file, str], logger: Logger, express_rules=Fal
|
||||
logger.error(f"Unsupported schema: {schema_name}")
|
||||
return
|
||||
|
||||
log_internal_cpp_errors(filename, logger)
|
||||
log_internal_cpp_errors(f, filename, logger)
|
||||
|
||||
schema = ifcopenshell.ifcopenshell_wrapper.schema_by_name(f.schema_identifier)
|
||||
used_guids: dict[str, ifcopenshell.entity_instance] = dict()
|
||||
@@ -490,7 +509,7 @@ def validate(f: Union[ifcopenshell.file, str], logger: Logger, express_rules=Fal
|
||||
# Re capturing the log when validate() is finished
|
||||
# iterating over every instance so that all attribute counts
|
||||
# are verified.
|
||||
log_internal_cpp_errors(filename, logger)
|
||||
log_internal_cpp_errors(f, filename, logger)
|
||||
|
||||
# Restore the original value for 'use_attribute_value_derived'
|
||||
ifcopenshell.ifcopenshell_wrapper.set_feature("use_attribute_value_derived", attribute_value_derived_org)
|
||||
|
||||
+1
-1
@@ -5,6 +5,6 @@ FILE_NAME('','2023-04-13T10:27:43',(),(),'IfcOpenShell v0.7.0-198fa67cc','IfcOpe
|
||||
FILE_SCHEMA(('IFC4'));
|
||||
ENDSEC;
|
||||
DATA;
|
||||
#1=IFCPRESENTATIONSTYLEASSIGNMENT((IFCNULLSTYLE('NOT_EXISTING_ENUM')));
|
||||
#1=IFCPRESENTATIONSTYLEASSIGNMENT((IFCNULLSTYLE(.NOT_EXISTING_ENUM.)));
|
||||
ENDSEC;
|
||||
END-ISO-10303-21;
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
ISO-10303-21;
|
||||
HEADER;
|
||||
FILE_DESCRIPTION(('ViewDefinition [CoordinationView]'),'2;1');
|
||||
FILE_NAME('','2023-04-13T10:27:43',(),(),'IfcOpenShell v0.7.0-198fa67cc','IfcOpenShell v0.7.0-198fa67cc','');
|
||||
FILE_SCHEMA(('IFC4'));
|
||||
ENDSEC;
|
||||
DATA;
|
||||
#1=IFCPROPERTYSINGLEVALUE('Test',$,IFCCOMPLEXNUMBER((0.,0.)),$);
|
||||
ENDSEC;
|
||||
END-ISO-10303-21;
|
||||
+1
-1
@@ -5,6 +5,6 @@ FILE_NAME('','2023-04-13T10:27:43',(),(),'IfcOpenShell v0.7.0-198fa67cc','IfcOpe
|
||||
FILE_SCHEMA(('IFC4'));
|
||||
ENDSEC;
|
||||
DATA;
|
||||
#1=IFCPRESENTATIONSTYLEASSIGNMENT((IFCNULLSTYLE('NULL')));
|
||||
#1=IFCPRESENTATIONSTYLEASSIGNMENT((IFCNULLSTYLE(.NULL.)));
|
||||
ENDSEC;
|
||||
END-ISO-10303-21;
|
||||
|
||||
@@ -28,9 +28,11 @@ class TestOpen:
|
||||
def test_open_ifcspf(self):
|
||||
assert ifcopenshell.open(TEST_FILE_DIR / "WallInstance_IFC4Add2.ifc")
|
||||
|
||||
@pytest.mark.skip("IFC-XML temporarily disabled")
|
||||
def test_open_ifcxml(self):
|
||||
assert ifcopenshell.open(TEST_FILE_DIR / "wall-with-opening-and-window.ifcxml")
|
||||
|
||||
@pytest.mark.skip("IFC-XML temporarily disabled")
|
||||
def test_open_ifc_zip_ifcxml_format(self):
|
||||
assert ifcopenshell.open(TEST_FILE_DIR / "wall-with-opening-and-window_ifcxml_format.ifczip")
|
||||
|
||||
@@ -49,16 +51,19 @@ class TestOpen:
|
||||
".ifcZIP",
|
||||
)
|
||||
|
||||
@pytest.mark.skip("IFC-XML temporarily disabled")
|
||||
def test_open_anyextension_ifcxml_format(self):
|
||||
assert ifcopenshell.open(
|
||||
TEST_FILE_DIR / "wall-with-opening-and-window_ifcxml_format.anyextension",
|
||||
".ifcXML",
|
||||
)
|
||||
|
||||
@pytest.mark.skip("IFC-XML temporarily disabled")
|
||||
def test_invalid_ifcspf(self):
|
||||
with pytest.raises(ifcopenshell.Error):
|
||||
assert ifcopenshell.open(TEST_FILE_DIR / "invalid.ifc")
|
||||
|
||||
@pytest.mark.skip("IFC-XML temporarily disabled")
|
||||
def test_invalid_ifcxml(self):
|
||||
with pytest.raises(IOError):
|
||||
assert ifcopenshell.open(TEST_FILE_DIR / "invalid.ifcxml")
|
||||
|
||||
@@ -29,11 +29,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class aggregate_of_instance;
|
||||
class aggregate_of_aggregate_of_instance;
|
||||
|
||||
namespace IfcUtil {
|
||||
class IfcBaseClass;
|
||||
|
||||
IFC_PARSE_API const char* ArgumentTypeToString(ArgumentType argument_type);
|
||||
|
||||
@@ -41,34 +37,5 @@ IFC_PARSE_API const char* ArgumentTypeToString(ArgumentType argument_type);
|
||||
IFC_PARSE_API bool valid_binary_string(const std::string& string);
|
||||
} // namespace IfcUtil
|
||||
|
||||
class IFC_PARSE_API Argument {
|
||||
public:
|
||||
virtual operator int() const;
|
||||
virtual operator bool() const;
|
||||
virtual operator boost::logic::tribool() const;
|
||||
virtual operator double() const;
|
||||
virtual operator std::string() const;
|
||||
virtual operator boost::dynamic_bitset<>() const;
|
||||
virtual operator IfcUtil::IfcBaseClass*() const;
|
||||
|
||||
virtual operator std::vector<int>() const;
|
||||
virtual operator std::vector<double>() const;
|
||||
virtual operator std::vector<std::string>() const;
|
||||
virtual operator std::vector<boost::dynamic_bitset<>>() const;
|
||||
virtual operator boost::shared_ptr<aggregate_of_instance>() const;
|
||||
|
||||
virtual operator std::vector<std::vector<int>>() const;
|
||||
virtual operator std::vector<std::vector<double>>() const;
|
||||
virtual operator boost::shared_ptr<aggregate_of_aggregate_of_instance>() const;
|
||||
|
||||
virtual bool isNull() const = 0;
|
||||
virtual unsigned int size() const = 0;
|
||||
|
||||
virtual IfcUtil::ArgumentType type() const = 0;
|
||||
virtual Argument* operator[](unsigned int index) const = 0;
|
||||
virtual std::string toString(bool upper = false) const = 0;
|
||||
|
||||
virtual ~Argument(){};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+937
-937
File diff suppressed because it is too large
Load Diff
+5397
-5726
File diff suppressed because it is too large
Load Diff
+934
-934
File diff suppressed because it is too large
Load Diff
+1116
-1116
File diff suppressed because it is too large
Load Diff
+6320
-6735
File diff suppressed because it is too large
Load Diff
+1113
-1113
File diff suppressed because it is too large
Load Diff
+1144
-1144
File diff suppressed because it is too large
Load Diff
+6495
-6916
File diff suppressed because it is too large
Load Diff
+1141
-1141
File diff suppressed because it is too large
Load Diff
+1166
-1166
File diff suppressed because it is too large
Load Diff
+6593
-7028
File diff suppressed because it is too large
Load Diff
+1163
-1163
File diff suppressed because it is too large
Load Diff
@@ -56,7 +56,6 @@
|
||||
#define SCHEMA_HAS_IfcBSplineCurveForm
|
||||
#define SCHEMA_HAS_IfcBSplineSurfaceForm
|
||||
#define SCHEMA_HAS_IfcBeamTypeEnum
|
||||
#define SCHEMA_HAS_IfcBearingTypeDisplacementEnum
|
||||
#define SCHEMA_HAS_IfcBearingTypeEnum
|
||||
#define SCHEMA_HAS_IfcBenchmarkEnum
|
||||
#define SCHEMA_HAS_IfcBendingParameterSelect
|
||||
@@ -142,8 +141,6 @@
|
||||
#define SCHEMA_HAS_IfcDocumentStatusEnum
|
||||
#define SCHEMA_HAS_IfcDoorPanelOperationEnum
|
||||
#define SCHEMA_HAS_IfcDoorPanelPositionEnum
|
||||
#define SCHEMA_HAS_IfcDoorStyleConstructionEnum
|
||||
#define SCHEMA_HAS_IfcDoorStyleOperationEnum
|
||||
#define SCHEMA_HAS_IfcDoorTypeEnum
|
||||
#define SCHEMA_HAS_IfcDoorTypeOperationEnum
|
||||
#define SCHEMA_HAS_IfcDoseEquivalentMeasure
|
||||
@@ -219,6 +216,7 @@
|
||||
#define SCHEMA_HAS_IfcIonConcentrationMeasure
|
||||
#define SCHEMA_HAS_IfcIsothermalMoistureCapacityMeasure
|
||||
#define SCHEMA_HAS_IfcJunctionBoxTypeEnum
|
||||
#define SCHEMA_HAS_IfcKerbTypeEnum
|
||||
#define SCHEMA_HAS_IfcKinematicViscosityMeasure
|
||||
#define SCHEMA_HAS_IfcKnotType
|
||||
#define SCHEMA_HAS_IfcLabel
|
||||
@@ -279,7 +277,6 @@
|
||||
#define SCHEMA_HAS_IfcNormalisedRatioMeasure
|
||||
#define SCHEMA_HAS_IfcNumericMeasure
|
||||
#define SCHEMA_HAS_IfcObjectReferenceSelect
|
||||
#define SCHEMA_HAS_IfcObjectTypeEnum
|
||||
#define SCHEMA_HAS_IfcObjectiveEnum
|
||||
#define SCHEMA_HAS_IfcOccupantTypeEnum
|
||||
#define SCHEMA_HAS_IfcOpeningElementTypeEnum
|
||||
@@ -386,6 +383,7 @@
|
||||
#define SCHEMA_HAS_IfcStairFlightTypeEnum
|
||||
#define SCHEMA_HAS_IfcStairTypeEnum
|
||||
#define SCHEMA_HAS_IfcStateEnum
|
||||
#define SCHEMA_HAS_IfcStrippedOptional
|
||||
#define SCHEMA_HAS_IfcStructuralActivityAssignmentSelect
|
||||
#define SCHEMA_HAS_IfcStructuralCurveActivityTypeEnum
|
||||
#define SCHEMA_HAS_IfcStructuralCurveMemberTypeEnum
|
||||
@@ -456,8 +454,6 @@
|
||||
#define SCHEMA_HAS_IfcWasteTerminalTypeEnum
|
||||
#define SCHEMA_HAS_IfcWindowPanelOperationEnum
|
||||
#define SCHEMA_HAS_IfcWindowPanelPositionEnum
|
||||
#define SCHEMA_HAS_IfcWindowStyleConstructionEnum
|
||||
#define SCHEMA_HAS_IfcWindowStyleOperationEnum
|
||||
#define SCHEMA_HAS_IfcWindowTypeEnum
|
||||
#define SCHEMA_HAS_IfcWindowTypePartitioningEnum
|
||||
#define SCHEMA_HAS_IfcWorkCalendarTypeEnum
|
||||
@@ -1789,6 +1785,7 @@
|
||||
#define SCHEMA_IfcIndexedPolyCurve_HAS_Segments
|
||||
#define SCHEMA_IfcIndexedPolyCurve_Segments_IS_OPTIONAL
|
||||
#define SCHEMA_IfcIndexedPolyCurve_HAS_SelfIntersect
|
||||
#define SCHEMA_IfcIndexedPolyCurve_SelfIntersect_IS_OPTIONAL
|
||||
#define SCHEMA_HAS_IfcIndexedPolygonalFace
|
||||
#define SCHEMA_IfcIndexedPolygonalFace_HAS_CoordIndex
|
||||
#define SCHEMA_IfcIndexedPolygonalFace_HAS_ToFaceSet
|
||||
@@ -1833,9 +1830,10 @@
|
||||
#define SCHEMA_HAS_IfcJunctionBoxType
|
||||
#define SCHEMA_IfcJunctionBoxType_HAS_PredefinedType
|
||||
#define SCHEMA_HAS_IfcKerb
|
||||
#define SCHEMA_IfcKerb_HAS_Mountable
|
||||
#define SCHEMA_IfcKerb_HAS_PredefinedType
|
||||
#define SCHEMA_IfcKerb_PredefinedType_IS_OPTIONAL
|
||||
#define SCHEMA_HAS_IfcKerbType
|
||||
#define SCHEMA_IfcKerbType_HAS_Mountable
|
||||
#define SCHEMA_IfcKerbType_HAS_PredefinedType
|
||||
#define SCHEMA_HAS_IfcLShapeProfileDef
|
||||
#define SCHEMA_IfcLShapeProfileDef_HAS_Depth
|
||||
#define SCHEMA_IfcLShapeProfileDef_HAS_Width
|
||||
@@ -2364,6 +2362,8 @@
|
||||
#define SCHEMA_IfcPolygonalBoundedHalfSpace_HAS_Position
|
||||
#define SCHEMA_IfcPolygonalBoundedHalfSpace_HAS_PolygonalBoundary
|
||||
#define SCHEMA_HAS_IfcPolygonalFaceSet
|
||||
#define SCHEMA_IfcPolygonalFaceSet_HAS_Closed
|
||||
#define SCHEMA_IfcPolygonalFaceSet_Closed_IS_OPTIONAL
|
||||
#define SCHEMA_IfcPolygonalFaceSet_HAS_Faces
|
||||
#define SCHEMA_IfcPolygonalFaceSet_HAS_PnIndex
|
||||
#define SCHEMA_IfcPolygonalFaceSet_PnIndex_IS_OPTIONAL
|
||||
@@ -2901,11 +2901,11 @@
|
||||
#define SCHEMA_IfcRelInterferesElements_HAS_RelatedElement
|
||||
#define SCHEMA_IfcRelInterferesElements_HAS_InterferenceGeometry
|
||||
#define SCHEMA_IfcRelInterferesElements_InterferenceGeometry_IS_OPTIONAL
|
||||
#define SCHEMA_IfcRelInterferesElements_HAS_InterferenceSpace
|
||||
#define SCHEMA_IfcRelInterferesElements_InterferenceSpace_IS_OPTIONAL
|
||||
#define SCHEMA_IfcRelInterferesElements_HAS_InterferenceType
|
||||
#define SCHEMA_IfcRelInterferesElements_InterferenceType_IS_OPTIONAL
|
||||
#define SCHEMA_IfcRelInterferesElements_HAS_ImpliedOrder
|
||||
#define SCHEMA_IfcRelInterferesElements_HAS_InterferenceSpace
|
||||
#define SCHEMA_IfcRelInterferesElements_InterferenceSpace_IS_OPTIONAL
|
||||
#define SCHEMA_HAS_IfcRelNests
|
||||
#define SCHEMA_IfcRelNests_HAS_RelatingObject
|
||||
#define SCHEMA_IfcRelNests_HAS_RelatedObjects
|
||||
@@ -3691,8 +3691,6 @@
|
||||
#define SCHEMA_IfcTendonType_SheathDiameter_IS_OPTIONAL
|
||||
#define SCHEMA_HAS_IfcTessellatedFaceSet
|
||||
#define SCHEMA_IfcTessellatedFaceSet_HAS_Coordinates
|
||||
#define SCHEMA_IfcTessellatedFaceSet_HAS_Closed
|
||||
#define SCHEMA_IfcTessellatedFaceSet_Closed_IS_OPTIONAL
|
||||
#define SCHEMA_IfcTessellatedFaceSet_HAS_HasColours
|
||||
#define SCHEMA_IfcTessellatedFaceSet_HAS_HasTextures
|
||||
#define SCHEMA_HAS_IfcTessellatedItem
|
||||
@@ -3814,6 +3812,8 @@
|
||||
#define SCHEMA_HAS_IfcTriangulatedFaceSet
|
||||
#define SCHEMA_IfcTriangulatedFaceSet_HAS_Normals
|
||||
#define SCHEMA_IfcTriangulatedFaceSet_Normals_IS_OPTIONAL
|
||||
#define SCHEMA_IfcTriangulatedFaceSet_HAS_Closed
|
||||
#define SCHEMA_IfcTriangulatedFaceSet_Closed_IS_OPTIONAL
|
||||
#define SCHEMA_IfcTriangulatedFaceSet_HAS_CoordIndex
|
||||
#define SCHEMA_IfcTriangulatedFaceSet_HAS_PnIndex
|
||||
#define SCHEMA_IfcTriangulatedFaceSet_PnIndex_IS_OPTIONAL
|
||||
@@ -4039,7 +4039,6 @@
|
||||
#define SCHEMA_HAS_IfcCorrectDimensions
|
||||
#define SCHEMA_HAS_IfcCorrectFillAreaStyle
|
||||
#define SCHEMA_HAS_IfcCorrectLocalPlacement
|
||||
#define SCHEMA_HAS_IfcCorrectObjectAssignment
|
||||
#define SCHEMA_HAS_IfcCorrectUnitAssignment
|
||||
#define SCHEMA_HAS_IfcCrossProduct
|
||||
#define SCHEMA_HAS_IfcCurveDim
|
||||
@@ -4049,7 +4048,6 @@
|
||||
#define SCHEMA_HAS_IfcDotProduct
|
||||
#define SCHEMA_HAS_IfcFirstProjAxis
|
||||
#define SCHEMA_HAS_IfcGetBasisSurface
|
||||
#define SCHEMA_HAS_IfcGradient
|
||||
#define SCHEMA_HAS_IfcListToArray
|
||||
#define SCHEMA_HAS_IfcLoopHeadToTail
|
||||
#define SCHEMA_HAS_IfcMakeArrayOfArray
|
||||
@@ -4057,6 +4055,7 @@
|
||||
#define SCHEMA_HAS_IfcNormalise
|
||||
#define SCHEMA_HAS_IfcOrthogonalComplement
|
||||
#define SCHEMA_HAS_IfcPathHeadToTail
|
||||
#define SCHEMA_HAS_IfcPointDim
|
||||
#define SCHEMA_HAS_IfcPointListDim
|
||||
#define SCHEMA_HAS_IfcSameAxis2Placement
|
||||
#define SCHEMA_HAS_IfcSameCartesianPoint
|
||||
@@ -4065,6 +4064,7 @@
|
||||
#define SCHEMA_HAS_IfcSameValue
|
||||
#define SCHEMA_HAS_IfcScalarTimesVector
|
||||
#define SCHEMA_HAS_IfcSecondProjAxis
|
||||
#define SCHEMA_HAS_IfcSegmentDim
|
||||
#define SCHEMA_HAS_IfcShapeRepresentationTypes
|
||||
#define SCHEMA_HAS_IfcSurfaceWeightsPositive
|
||||
#define SCHEMA_HAS_IfcTaperedSweptAreaProfiles
|
||||
|
||||
+3742
-17055
File diff suppressed because one or more lines are too long
+10088
-15679
File diff suppressed because one or more lines are too long
+1304
-1618
File diff suppressed because one or more lines are too long
+1254
-1254
File diff suppressed because it is too large
Load Diff
+7060
-7547
File diff suppressed because it is too large
Load Diff
+1251
-1251
File diff suppressed because it is too large
Load Diff
+1254
-1254
File diff suppressed because it is too large
Load Diff
+7060
-7547
File diff suppressed because it is too large
Load Diff
+1251
-1251
File diff suppressed because it is too large
Load Diff
+1254
-1254
File diff suppressed because it is too large
Load Diff
+7014
-7499
File diff suppressed because it is too large
Load Diff
+1251
-1251
File diff suppressed because it is too large
Load Diff
+1263
-1263
File diff suppressed because it is too large
Load Diff
+7075
-7566
File diff suppressed because it is too large
Load Diff
+1260
-1260
File diff suppressed because it is too large
Load Diff
+1256
-1256
File diff suppressed because it is too large
Load Diff
+7033
-7526
File diff suppressed because it is too large
Load Diff
+1253
-1253
File diff suppressed because it is too large
Load Diff
+1255
-1255
File diff suppressed because it is too large
Load Diff
+7041
-7534
File diff suppressed because it is too large
Load Diff
+1252
-1252
File diff suppressed because it is too large
Load Diff
+1249
-1249
File diff suppressed because it is too large
Load Diff
+7030
-7517
File diff suppressed because it is too large
Load Diff
+1246
-1246
File diff suppressed because it is too large
Load Diff
+79
-31
@@ -29,9 +29,12 @@
|
||||
#include <atomic>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
class Argument;
|
||||
class aggregate_of_instance;
|
||||
|
||||
namespace IfcParse {
|
||||
class IfcFile;
|
||||
}
|
||||
|
||||
namespace IfcUtil {
|
||||
|
||||
class IFC_PARSE_API IfcBaseInterface {
|
||||
@@ -54,6 +57,7 @@ class IFC_PARSE_API IfcBaseInterface {
|
||||
virtual const IfcEntityInstanceData& data() const = 0;
|
||||
virtual IfcEntityInstanceData& data() = 0;
|
||||
virtual const IfcParse::declaration& declaration() const = 0;
|
||||
virtual ~IfcBaseInterface() {}
|
||||
|
||||
template <class T>
|
||||
T* as(bool do_throw = false) {
|
||||
@@ -82,36 +86,42 @@ class IFC_PARSE_API IfcBaseInterface {
|
||||
};
|
||||
|
||||
class IFC_PARSE_API IfcBaseClass : public virtual IfcBaseInterface {
|
||||
private:
|
||||
uint32_t identity_;
|
||||
protected:
|
||||
static std::atomic_uint32_t counter_;
|
||||
|
||||
protected:
|
||||
IfcEntityInstanceData* data_;
|
||||
uint32_t identity_;
|
||||
public:
|
||||
uint32_t id_;
|
||||
IfcParse::IfcFile* file_;
|
||||
protected:
|
||||
IfcEntityInstanceData data_;
|
||||
|
||||
static bool is_null(const IfcBaseClass* not_this) {
|
||||
return not_this == nullptr;
|
||||
}
|
||||
public:
|
||||
IfcBaseClass(IfcEntityInstanceData&& data)
|
||||
: identity_(counter_++)
|
||||
, id_(0)
|
||||
, file_(nullptr)
|
||||
, data_(std::move(data))
|
||||
{}
|
||||
|
||||
public:
|
||||
IfcBaseClass() : identity_(counter_++),
|
||||
data_(0) {}
|
||||
IfcBaseClass(IfcEntityInstanceData* data) : identity_(counter_++),
|
||||
data_(data) {}
|
||||
virtual ~IfcBaseClass() { delete data_; }
|
||||
|
||||
const IfcEntityInstanceData& data() const { return *data_; }
|
||||
IfcEntityInstanceData& data() { return *data_; }
|
||||
void data(IfcEntityInstanceData* data);
|
||||
const IfcEntityInstanceData& data() const { return data_; }
|
||||
IfcEntityInstanceData& data() { return data_; }
|
||||
|
||||
virtual const IfcParse::declaration& declaration() const = 0;
|
||||
|
||||
template <typename T>
|
||||
void set_value(int index, const T& value);
|
||||
void set_attribute_value(size_t i, const T& t);
|
||||
|
||||
void unset_value(int index);
|
||||
template <typename T>
|
||||
void set_attribute_value(const std::string& name, const T& t);
|
||||
|
||||
void unset_attribute_value(size_t i);
|
||||
|
||||
uint32_t identity() const { return identity_; }
|
||||
|
||||
uint32_t id() const { return id_; }
|
||||
|
||||
void toString(std::ostream&, bool upper = false) const;
|
||||
};
|
||||
|
||||
class IFC_PARSE_API IfcLateBoundEntity : public IfcBaseClass {
|
||||
@@ -119,7 +129,7 @@ class IFC_PARSE_API IfcLateBoundEntity : public IfcBaseClass {
|
||||
const IfcParse::declaration* decl_;
|
||||
|
||||
public:
|
||||
IfcLateBoundEntity(const IfcParse::declaration* decl, IfcEntityInstanceData* data) : IfcBaseClass(data),
|
||||
IfcLateBoundEntity(const IfcParse::declaration* decl, IfcEntityInstanceData&& data) : IfcBaseClass(std::move(data)),
|
||||
decl_(decl) {}
|
||||
|
||||
virtual const IfcParse::declaration& declaration() const {
|
||||
@@ -129,12 +139,15 @@ class IFC_PARSE_API IfcLateBoundEntity : public IfcBaseClass {
|
||||
|
||||
class IFC_PARSE_API IfcBaseEntity : public IfcBaseClass {
|
||||
public:
|
||||
IfcBaseEntity() : IfcBaseClass() {}
|
||||
IfcBaseEntity(IfcEntityInstanceData* data) : IfcBaseClass(data) {}
|
||||
IfcBaseEntity(IfcEntityInstanceData&& data) : IfcBaseClass(std::move(data)) {}
|
||||
|
||||
IfcBaseEntity(size_t n)
|
||||
: IfcBaseClass(IfcEntityInstanceData(storage_t(n)))
|
||||
{}
|
||||
|
||||
virtual const IfcParse::entity& declaration() const = 0;
|
||||
|
||||
Argument* get(const std::string& name) const;
|
||||
AttributeValue get(const std::string& name) const;
|
||||
|
||||
template <typename T>
|
||||
T get_value(const std::string& name) const;
|
||||
@@ -143,13 +156,20 @@ class IFC_PARSE_API IfcBaseEntity : public IfcBaseClass {
|
||||
T get_value(const std::string& name, const T& default_value) const;
|
||||
|
||||
boost::shared_ptr<aggregate_of_instance> get_inverse(const std::string& name) const;
|
||||
|
||||
unsigned set_id(const boost::optional<unsigned>& i);
|
||||
};
|
||||
|
||||
// TODO: Investigate whether these should be template classes instead
|
||||
class IFC_PARSE_API IfcBaseType : public IfcBaseClass {
|
||||
public:
|
||||
IfcBaseType() : IfcBaseClass() {}
|
||||
IfcBaseType(IfcEntityInstanceData* data) : IfcBaseClass(data) {}
|
||||
IfcBaseType(IfcEntityInstanceData&& data)\
|
||||
: IfcBaseClass(std::move(data))
|
||||
{}
|
||||
|
||||
IfcBaseType()
|
||||
: IfcBaseClass(IfcEntityInstanceData(storage_t(1)))
|
||||
{}
|
||||
|
||||
virtual const IfcParse::declaration& declaration() const = 0;
|
||||
};
|
||||
@@ -159,18 +179,46 @@ class IFC_PARSE_API IfcBaseType : public IfcBaseClass {
|
||||
namespace IfcUtil {
|
||||
template <typename T>
|
||||
T IfcBaseEntity::get_value(const std::string& name) const {
|
||||
auto* attr = get(name);
|
||||
return (T)*attr;
|
||||
auto attr = get(name);
|
||||
return (T) attr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T IfcBaseEntity::get_value(const std::string& name, const T& default_value) const {
|
||||
auto* attr = get(name);
|
||||
if (attr->isNull()) {
|
||||
auto attr = get(name);
|
||||
if (attr.isNull()) {
|
||||
return default_value;
|
||||
}
|
||||
return (T)*attr;
|
||||
return (T) attr;
|
||||
}
|
||||
|
||||
} // namespace IfcUtil
|
||||
|
||||
template <class U>
|
||||
typename U::list::ptr aggregate_of_instance::as() {
|
||||
typename U::list::ptr result(new typename U::list);
|
||||
for (it i = begin(); i != end(); ++i) {
|
||||
if ((*i)->template as<U>()) {
|
||||
result->push((*i)->template as<U>());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class U>
|
||||
typename aggregate_of_aggregate_of<U>::ptr aggregate_of_aggregate_of_instance::as() {
|
||||
typename aggregate_of_aggregate_of<U>::ptr result(new aggregate_of_aggregate_of<U>);
|
||||
for (outer_it outer = begin(); outer != end(); ++outer) {
|
||||
const std::vector<IfcUtil::IfcBaseClass*>& from = *outer;
|
||||
typename std::vector<U*> to;
|
||||
for (inner_it inner = from.begin(); inner != from.end(); ++inner) {
|
||||
if ((*inner)->template as<U>()) {
|
||||
to.push_back((*inner)->template as<U>());
|
||||
}
|
||||
}
|
||||
result->push(to);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
#define ARBITRARY (1 << 7)
|
||||
#define EXTENDED2 (1 << 8)
|
||||
#define EXTENDED4 (1 << 9)
|
||||
#define HEX(N) (1 << (9 + N))
|
||||
#define HEX(N) (1 << (9 + (N)))
|
||||
#define THIRD_SOLIDUS (1 << 18)
|
||||
#define ENDEXTENDED_X (1 << 19)
|
||||
#define ENDEXTENDED_0 (1 << 20)
|
||||
@@ -52,25 +52,24 @@
|
||||
#define ENCOUNTERED_HEX (1 << 23)
|
||||
|
||||
// FIXME: These probably need to be less forgiving in terms of wrongly defined sequences
|
||||
#define EXPECTS_ALPHABET(S) (S & FIRST_SOLIDUS)
|
||||
#define EXPECTS_PAGE(S) (S & FIRST_SOLIDUS)
|
||||
#define EXPECTS_ARBITRARY(S) (S & FIRST_SOLIDUS)
|
||||
#define EXPECTS_N_OR_F(S) (S & FIRST_SOLIDUS && !(S & ARBITRARY))
|
||||
#define EXPECTS_ARBITRARY2(S) (S & ARBITRARY && !(S & SECOND_SOLIDUS))
|
||||
#define EXPECTS_ALPHABET_DEFINITION(S) (S & FIRST_SOLIDUS && S & ALPHABET)
|
||||
#define EXPECTS_SOLIDUS(S) (S & ALPHABET_DEFINITION || S & PAGE || S & ARBITRARY || S & EXTENDED2 || S & EXTENDED4 || S & ENDEXTENDED_0 || S & IGNORED_DIRECTIVE || (S & EXTENDED4 && S & HEX(8)) || (S & EXTENDED2 && S & HEX(4)))
|
||||
#define EXPECTS_CHARACTER(S) (S & PAGE && S & SECOND_SOLIDUS)
|
||||
#define EXPECTS_HEX(S) (S & HEX(1) || S & HEX(3) || S & HEX(5) || S & HEX(6) || S & HEX(7) || (S & ARBITRARY && S & SECOND_SOLIDUS) || (S & EXTENDED2 && S & HEX(2)) || (S & EXTENDED4 && S & HEX(4)))
|
||||
#define EXPECTS_ENDEXTENDED_X(S) (S & THIRD_SOLIDUS)
|
||||
#define EXPECTS_ENDEXTENDED_0(S) (S & ENDEXTENDED_X)
|
||||
#define EXPECTS_ALPHABET(S) ((S) & FIRST_SOLIDUS)
|
||||
#define EXPECTS_PAGE(S) ((S) & FIRST_SOLIDUS)
|
||||
#define EXPECTS_ARBITRARY(S) ((S) & FIRST_SOLIDUS)
|
||||
#define EXPECTS_N_OR_F(S) ((S) & FIRST_SOLIDUS && !((S) & ARBITRARY))
|
||||
#define EXPECTS_ARBITRARY2(S) ((S) & ARBITRARY && !((S) & SECOND_SOLIDUS))
|
||||
#define EXPECTS_ALPHABET_DEFINITION(S) ((S) & FIRST_SOLIDUS && (S) & ALPHABET)
|
||||
#define EXPECTS_SOLIDUS(S) ((S) & ALPHABET_DEFINITION || (S) & PAGE || (S) & ARBITRARY || (S) & EXTENDED2 || (S) & EXTENDED4 || (S) & ENDEXTENDED_0 || (S) & IGNORED_DIRECTIVE || ((S) & EXTENDED4 && (S) & HEX(8)) || ((S) & EXTENDED2 && (S) & HEX(4)))
|
||||
#define EXPECTS_CHARACTER(S) ((S) & PAGE && (S) & SECOND_SOLIDUS)
|
||||
#define EXPECTS_HEX(S) ((S) & HEX(1) || (S) & HEX(3) || (S) & HEX(5) || (S) & HEX(6) || (S) & HEX(7) || ((S) & ARBITRARY && (S) & SECOND_SOLIDUS) || ((S) & EXTENDED2 && (S) & HEX(2)) || ((S) & EXTENDED4 && (S) & HEX(4)))
|
||||
#define EXPECTS_ENDEXTENDED_X(S) ((S) & THIRD_SOLIDUS)
|
||||
#define EXPECTS_ENDEXTENDED_0(S) ((S) & ENDEXTENDED_X)
|
||||
|
||||
#define IS_VALID_ALPHABET_DEFINITION(C) (C >= 0x41 && C <= 0x49)
|
||||
#define IS_HEXADECIMAL(C) ((C >= 0x30 && C <= 0x39) || (C >= 0x41 && C <= 0x46))
|
||||
#define HEX_TO_INT(C) ((C >= 0x30 && C <= 0x39) ? C - 0x30 : (C + 10) - 0x41)
|
||||
#define CLEAR_HEX(C) (C &= ~(HEX(1) | HEX(2) | HEX(3) | HEX(4) | HEX(5) | HEX(6) | HEX(7) | HEX(8)))
|
||||
#define IS_VALID_ALPHABET_DEFINITION(C) ((C) >= 0x41 && (C) <= 0x49)
|
||||
#define IS_HEXADECIMAL(C) (((C) >= 0x30 && (C) <= 0x39) || ((C) >= 0x41 && (C) <= 0x46))
|
||||
#define HEX_TO_INT(C) (((C) >= 0x30 && (C) <= 0x39) ? (C) - 0x30 : ((C) + 10) - 0x41)
|
||||
#define CLEAR_HEX(C) ((C) &= ~(HEX(1) | HEX(2) | HEX(3) | HEX(4) | HEX(5) | HEX(6) | HEX(7) | HEX(8)))
|
||||
|
||||
using namespace IfcParse;
|
||||
using namespace IfcWrite;
|
||||
|
||||
IfcCharacterDecoder::IfcCharacterDecoder(IfcParse::IfcSpfStream* stream) {
|
||||
stream_ = stream;
|
||||
@@ -81,7 +80,7 @@ IfcCharacterDecoder::~IfcCharacterDecoder() {
|
||||
}
|
||||
|
||||
namespace {
|
||||
static unsigned int reference_helper = 0;
|
||||
unsigned int reference_helper = 0;
|
||||
|
||||
class pure_impure_helper {
|
||||
private:
|
||||
@@ -420,14 +419,36 @@ std::wstring IfcUtil::convert_utf8(const std::string& string) {
|
||||
// bug in msvc 2015 and 2017, unsure if fixed in later versions
|
||||
|
||||
std::u32string IfcUtil::convert_utf8_to_utf32(const std::string& s) {
|
||||
auto converted = std::wstring_convert<std::codecvt_utf8<int32_t>, int32_t>().from_bytes(s);
|
||||
return std::u32string(reinterpret_cast<char32_t const*>(converted.data()));
|
||||
bool is_ascii = true;
|
||||
for (char c : s) {
|
||||
if (static_cast<unsigned char>(c) >= 128) {
|
||||
is_ascii = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_ascii) {
|
||||
return std::u32string(s.begin(), s.end());
|
||||
} else {
|
||||
auto converted = std::wstring_convert<std::codecvt_utf8<int32_t>, int32_t>().from_bytes(s);
|
||||
return std::u32string(reinterpret_cast<char32_t const*>(converted.data()));
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
std::u32string IfcUtil::convert_utf8_to_utf32(const std::string& string) {
|
||||
return std::wstring_convert<std::codecvt_utf8<std::u32string::value_type>, std::u32string::value_type>().from_bytes(string);
|
||||
std::u32string IfcUtil::convert_utf8_to_utf32(const std::string& s) {
|
||||
bool is_ascii = true;
|
||||
for (char c : s) {
|
||||
if (static_cast<unsigned char>(c) >= 128) {
|
||||
is_ascii = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_ascii) {
|
||||
return std::u32string(s.begin(), s.end());
|
||||
}
|
||||
return std::wstring_convert<std::codecvt_utf8<std::u32string::value_type>, std::u32string::value_type>().from_bytes(s);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -68,7 +68,7 @@ class IFC_PARSE_API IfcCharacterDecoder {
|
||||
|
||||
} // namespace IfcParse
|
||||
|
||||
namespace IfcWrite {
|
||||
namespace IfcParse {
|
||||
|
||||
class IFC_PARSE_API IfcCharacterEncoder {
|
||||
private:
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
#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& /*unused*/) const { return 0; }
|
||||
int operator()(const empty_aggregate_of_aggregate_t& /*unused*/) 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
|
||||
{
|
||||
if (array_->has<bool>(index_)) {
|
||||
return array_->get<bool>(index_);
|
||||
}
|
||||
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_));
|
||||
}
|
||||
@@ -21,90 +21,179 @@
|
||||
#define IFCENTITYINSTANCEDATA_H
|
||||
|
||||
#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 Argument;
|
||||
class aggregate_of_instance;
|
||||
namespace IfcParse {
|
||||
class IfcFile;
|
||||
}
|
||||
class EnumerationReference {
|
||||
private:
|
||||
const IfcParse::enumeration_type* enumeration_;
|
||||
size_t index_;
|
||||
public:
|
||||
|
||||
EnumerationReference(const IfcParse::enumeration_type* enumeration, size_t index)
|
||||
: enumeration_(enumeration)
|
||||
, index_(index)
|
||||
{}
|
||||
|
||||
const char* value() const {
|
||||
return enumeration_->lookup_enum_value(index_);
|
||||
}
|
||||
|
||||
size_t index() const {
|
||||
return index_;
|
||||
}
|
||||
|
||||
const IfcParse::enumeration_type* enumeration() const {
|
||||
return enumeration_;
|
||||
}
|
||||
};
|
||||
class Blank {};
|
||||
class Derived {};
|
||||
class empty_aggregate_t {};
|
||||
class empty_aggregate_of_aggregate_t {};
|
||||
|
||||
typedef VariantArray <
|
||||
// A null argument, it will always serialize to $
|
||||
Blank,
|
||||
// @todo Derived is not really necessary anymore, just serialize correctly based on schema
|
||||
// A derived argument, it will always serialize to *
|
||||
Derived,
|
||||
// An integer argument, e.g. 123
|
||||
|
||||
// SCALARS:
|
||||
int,
|
||||
// A boolean argument, it will serialize to either .T. or .F.
|
||||
bool,
|
||||
// A logical argument, it will serialize to either .T. or .F. or .U.
|
||||
boost::logic::tribool,
|
||||
// A floating point argument, e.g. 12.3
|
||||
double,
|
||||
// A character string argument, e.g. 'IfcOpenShell'
|
||||
std::string,
|
||||
// A binary argument, e.g. "092A" -> 100100101010
|
||||
boost::dynamic_bitset<>,
|
||||
// An enumeration argument, e.g. .USERDEFINED.
|
||||
// To initialize the argument a string representation
|
||||
// has to be explicitly passed of the enumeration value
|
||||
// which is stored internally as an integer. The argument
|
||||
// itself does not keep track of what schema enumeration
|
||||
// type is represented.
|
||||
EnumerationReference,
|
||||
// An entity instance argument. It will either serialize to
|
||||
// e.g. #123 or datatype identifier for simple types, e.g.
|
||||
// IFCREAL(12.3)
|
||||
IfcUtil::IfcBaseClass*,
|
||||
|
||||
// AGGREGATES:
|
||||
empty_aggregate_t,
|
||||
// An aggregate of integers, e.g. (1,2,3)
|
||||
std::vector<int>,
|
||||
// An aggregate of floats, e.g. (12.3,4.)
|
||||
std::vector<double>,
|
||||
// An aggregate of strings, e.g. ('Ifc','Open','Shell')
|
||||
std::vector<std::string>,
|
||||
// An aggregate of binaries, e.g. ("23B", "092A") -> (111011, 100100101010)
|
||||
std::vector<boost::dynamic_bitset<>>,
|
||||
// An aggregate of entity instances. It will either serialize to
|
||||
// e.g. (#1,#2,#3) or datatype identifier for simple types,
|
||||
// e.g. (IFCREAL(1.2),IFCINTEGER(3.))
|
||||
aggregate_of_instance::ptr,
|
||||
|
||||
// AGGREGATES OF AGGREGATES:
|
||||
empty_aggregate_of_aggregate_t,
|
||||
// An aggregate of an aggregate of ints. E.g. ((1, 2), (3))
|
||||
std::vector<std::vector<int>>,
|
||||
// An aggregate of an aggregate of floats. E.g. ((1., 2.3), (4.))
|
||||
std::vector<std::vector<double>>,
|
||||
// An aggregate of an aggregate of entities. E.g. ((#1, #2), (#3))
|
||||
aggregate_of_aggregate_of_instance::ptr
|
||||
> storage_t;
|
||||
|
||||
struct MutableAttributeValue {
|
||||
int name_;
|
||||
uint8_t index_;
|
||||
};
|
||||
|
||||
// short lived
|
||||
struct AttributeValue {
|
||||
const storage_t* array_;
|
||||
uint8_t index_;
|
||||
|
||||
AttributeValue()
|
||||
: array_(nullptr)
|
||||
, index_(0)
|
||||
{}
|
||||
|
||||
AttributeValue(const storage_t* arr, uint8_t index)
|
||||
: array_(arr)
|
||||
, index_(index)
|
||||
{}
|
||||
|
||||
operator int() const;
|
||||
operator bool() const;
|
||||
operator boost::logic::tribool() const;
|
||||
operator double() const;
|
||||
operator std::string() const;
|
||||
operator boost::dynamic_bitset<>() const;
|
||||
operator IfcUtil::IfcBaseClass* () const;
|
||||
|
||||
operator std::vector<int>() const;
|
||||
operator std::vector<double>() const;
|
||||
operator std::vector<std::string>() const;
|
||||
operator std::vector<boost::dynamic_bitset<>>() const;
|
||||
operator boost::shared_ptr<aggregate_of_instance>() const;
|
||||
|
||||
operator std::vector<std::vector<int>>() const;
|
||||
operator std::vector<std::vector<double>>() const;
|
||||
operator boost::shared_ptr<aggregate_of_aggregate_of_instance>() const;
|
||||
|
||||
bool isNull() const;
|
||||
unsigned int size() const;
|
||||
|
||||
IfcUtil::ArgumentType type() const;
|
||||
};
|
||||
|
||||
class IFC_PARSE_API IfcEntityInstanceData {
|
||||
public:
|
||||
// Public for backwards compatibility
|
||||
IfcParse::IfcFile* file;
|
||||
storage_t storage_;
|
||||
|
||||
protected:
|
||||
unsigned id_;
|
||||
const IfcParse::declaration* type_;
|
||||
mutable Argument** attributes_;
|
||||
unsigned offset_in_file_;
|
||||
IfcEntityInstanceData(storage_t&& storage)
|
||||
: storage_(std::move(storage))
|
||||
{}
|
||||
|
||||
public:
|
||||
IfcEntityInstanceData(const IfcParse::declaration* type,
|
||||
IfcParse::IfcFile* file,
|
||||
unsigned id = 0,
|
||||
unsigned offset_in_file = 0)
|
||||
: file(file),
|
||||
id_(id),
|
||||
type_(type),
|
||||
attributes_(0),
|
||||
offset_in_file_(offset_in_file) {}
|
||||
IfcEntityInstanceData(IfcEntityInstanceData&& other) noexcept
|
||||
: storage_(std::move(other.storage_))
|
||||
{}
|
||||
|
||||
IfcEntityInstanceData(IfcParse::IfcFile* file_, size_t size)
|
||||
: file(file_),
|
||||
id_(0),
|
||||
type_(0),
|
||||
attributes_(new Argument* [size] { 0 }),
|
||||
offset_in_file_(0) {}
|
||||
IfcEntityInstanceData(const IfcEntityInstanceData& data);
|
||||
|
||||
IfcEntityInstanceData(const IfcParse::declaration* type)
|
||||
: file(0),
|
||||
id_(0),
|
||||
type_(type),
|
||||
attributes_(new Argument* [getArgumentCount()] { 0 }),
|
||||
offset_in_file_(0) {}
|
||||
IfcEntityInstanceData& operator=(IfcEntityInstanceData&& other) {
|
||||
if (this != &other) {
|
||||
storage_ = std::move(other.storage_);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void load() const;
|
||||
AttributeValue get_attribute_value(size_t index) const;
|
||||
|
||||
IfcEntityInstanceData(const IfcEntityInstanceData& data);
|
||||
/*
|
||||
template <typename T>
|
||||
void set_attribute_value(size_t index, const T& t);
|
||||
|
||||
virtual ~IfcEntityInstanceData();
|
||||
void set_attribute_value(size_t index, AttributeValue&, IfcUtil::ArgumentType attr_type = IfcUtil::Argument_UNKNOWN);
|
||||
*/
|
||||
|
||||
boost::shared_ptr<aggregate_of_instance> getInverse(const IfcParse::declaration* type, int attribute_index) const;
|
||||
|
||||
Argument* getArgument(size_t index) const;
|
||||
|
||||
// NB: This makes a copy of the argument if make_copy is set
|
||||
void setArgument(size_t ibdex, Argument* argument, IfcUtil::ArgumentType attr_type = IfcUtil::Argument_UNKNOWN, bool make_copy = false);
|
||||
|
||||
virtual size_t getArgumentCount() const {
|
||||
if (type_ == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (type_->as_entity() != nullptr) {
|
||||
return type_->as_entity()->attribute_count();
|
||||
}
|
||||
return 1;
|
||||
size_t size() const {
|
||||
return storage_.size();
|
||||
}
|
||||
|
||||
void clearArguments();
|
||||
|
||||
const IfcParse::declaration* type() const {
|
||||
return type_;
|
||||
}
|
||||
|
||||
std::string toString(bool upper = false) const;
|
||||
|
||||
unsigned int id() const { return id_; }
|
||||
unsigned int offset_in_file() const { return offset_in_file_; }
|
||||
|
||||
// NB: const ommitted for lazy loading
|
||||
Argument**& attributes() const { return attributes_; }
|
||||
|
||||
unsigned set_id(boost::optional<unsigned> id = boost::none);
|
||||
void toString(std::ostream&, bool upper = false, const IfcParse::entity* ent = nullptr) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,274 @@
|
||||
#include "IfcFile.h"
|
||||
#include "IfcLogger.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 {
|
||||
template<typename Variant, typename T>
|
||||
struct is_type_in_variant;
|
||||
|
||||
template<typename T, typename... Types>
|
||||
struct is_type_in_variant<boost::variant<Types...>, T>
|
||||
{
|
||||
static constexpr bool value = (std::is_same<T, Types>::value || ...);
|
||||
};
|
||||
|
||||
template<typename Variant, typename T>
|
||||
constexpr bool is_type_in_variant_v = is_type_in_variant<Variant, T>::value;
|
||||
|
||||
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()) {
|
||||
try {
|
||||
fn(EnumerationReference(decl->as_enumeration_type(), decl->as_enumeration_type()->lookup_enum_offset(IfcParse::TokenFunc::asStringRef(t))));
|
||||
} catch (IfcParse::IfcException& e) {
|
||||
Logger::Error(e);
|
||||
}
|
||||
}
|
||||
} else if (t.type == IfcParse::Token_FLOAT) {
|
||||
fn(IfcParse::TokenFunc::asFloat(t));
|
||||
} else if (t.type == IfcParse::Token_IDENTIFIER) {
|
||||
fn(IfcParse::reference_or_simple_type{ 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));
|
||||
} else if (t.type == IfcParse::Token_OPERATOR && t.value_char == '*') {
|
||||
// This is only in place for the validator
|
||||
fn(Derived{});
|
||||
}
|
||||
}
|
||||
|
||||
template <size_t Depth, typename Fn>
|
||||
void construct_(IfcParse::parse_context& p, const IfcParse::aggregation_type* aggr, Fn fn) {
|
||||
if (p.tokens_.empty()) {
|
||||
// @todo instead of ugly if-else we could also default initialize the respective
|
||||
// variant types below.
|
||||
if (aggr) {
|
||||
auto aggr_type = IfcUtil::make_aggregate(IfcUtil::from_parameter_type(aggr->type_of_element()));
|
||||
if (aggr_type == IfcUtil::Argument_AGGREGATE_OF_INT) {
|
||||
fn(std::vector<int>{});
|
||||
} else if (aggr_type == IfcUtil::Argument_AGGREGATE_OF_DOUBLE) {
|
||||
fn(std::vector<double>{});
|
||||
} else if (aggr_type == IfcUtil::Argument_AGGREGATE_OF_STRING) {
|
||||
fn(std::vector<std::string>{});
|
||||
} else if (aggr_type == IfcUtil::Argument_AGGREGATE_OF_BINARY) {
|
||||
fn(std::vector<boost::dynamic_bitset<>>{});
|
||||
} else if (aggr_type == IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE) {
|
||||
fn(aggregate_of_instance::ptr(new aggregate_of_instance));
|
||||
} else if (aggr_type == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT) {
|
||||
fn(std::vector<std::vector<int>>{});
|
||||
} else if (aggr_type == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE) {
|
||||
fn(std::vector<std::vector<double>>{});
|
||||
} else if (aggr_type == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE) {
|
||||
fn(aggregate_of_aggregate_of_instance::ptr(new aggregate_of_aggregate_of_instance));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
auto append_to_aggregate_storage = [&aggregate_storage](const auto& v) {
|
||||
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 {
|
||||
auto* vec_ptr = boost::get<std::vector<std::decay_t<decltype(v)>>>(&aggregate_storage);
|
||||
if (vec_ptr) {
|
||||
vec_ptr->push_back(v);
|
||||
} else {
|
||||
// @todo would be cool if we can trace this back to file offset
|
||||
auto current = boost::apply_visitor([](auto v) {
|
||||
if constexpr (!std::is_same_v<decltype(v), Blank>) {
|
||||
return std::string(typeid(typename decltype(v)::value_type).name());
|
||||
} else {
|
||||
// Cannot occur as aggregate_storage.which() == 0
|
||||
// is another branch several statements up. But is
|
||||
// needed for consistency of return type.
|
||||
return std::string{};
|
||||
}
|
||||
}, aggregate_storage);
|
||||
Logger::Error("Inconsistent aggregate valuation while attempting to append " + std::string(typeid(decltype(v)).name()) + " to an aggregate of " + current);
|
||||
|
||||
// @todo boolean -> logical upgrade
|
||||
// wait a second... there are no aggregate of bool / logical in the schema..
|
||||
//
|
||||
// if constexpr (std::is_same_v<std::decay_t<decltype(v)>, bool>) {
|
||||
// auto* vec_ptr = boost::get<std::vector<boost::tribool>(&aggregate_storage);
|
||||
// vec_ptr->push_back(v);
|
||||
// }
|
||||
// if constexpr (std::is_same_v<std::decay_t<decltype(v)>, boost::tribool>) {
|
||||
// auto* vec_ptr = boost::get<std::vector<bool>(&aggregate_storage);
|
||||
// std::vector<boost::tribool> ps(vec_ptr->begin(), vec_ptr->end());
|
||||
// ps.push_back(v);
|
||||
// aggregate_storage = ps;
|
||||
// }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// @todo would be cool if we can trace this back to file offset
|
||||
Logger::Error(std::string("Aggregates of ") + typeid(decltype(v)).name() + " are not supported in the IfcOpenShell parser");
|
||||
}
|
||||
};
|
||||
|
||||
for (auto& t : p.tokens_) {
|
||||
boost::apply_visitor([&aggregate_storage, &append_to_aggregate_storage, aggr](const auto& v) {
|
||||
if constexpr (std::is_same_v<std::decay_t<decltype(v)>, IfcParse::Token>) {
|
||||
// @todo get aggregate of enumeration
|
||||
dispatch_token(v, aggr && aggr->type_of_element()->as_named_type() ? aggr->type_of_element()->as_named_type()->declared_type() : nullptr, append_to_aggregate_storage);
|
||||
} else if constexpr (std::is_same_v<std::decay_t<decltype(v)>, IfcParse::parse_context*>) {
|
||||
// nested list
|
||||
if constexpr (Depth < 3) {
|
||||
construct_<Depth + 1>(*v, nullptr, append_to_aggregate_storage);
|
||||
}
|
||||
} else {
|
||||
append_to_aggregate_storage(IfcParse::reference_or_simple_type{ v });
|
||||
}
|
||||
}, t);
|
||||
}
|
||||
|
||||
boost::apply_visitor(fn, aggregate_storage);
|
||||
}
|
||||
}
|
||||
|
||||
IfcEntityInstanceData IfcParse::parse_context::construct(int name, unresolved_references& references_to_resolve, const IfcParse::declaration* decl, boost::optional<size_t> expected_size) {
|
||||
std::vector<const IfcParse::parameter_type*> parameter_types;
|
||||
std::unique_ptr<IfcParse::named_type> transient_named_type;
|
||||
|
||||
if ((decl != nullptr) && (decl->as_type_declaration() != nullptr)) {
|
||||
parameter_types = { decl->as_type_declaration()->declared_type() };
|
||||
} else if ((decl != nullptr) && (decl->as_enumeration_type() != nullptr)) {
|
||||
transient_named_type.reset(new IfcParse::named_type(const_cast<IfcParse::declaration*>(decl)));
|
||||
parameter_types = { &*transient_named_type };
|
||||
} else if ((decl != nullptr) && (decl->as_entity() != nullptr)) {
|
||||
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();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (((decl != nullptr) && (tokens_.size() != parameter_types.size())) ||
|
||||
expected_size && *expected_size != tokens_.size())
|
||||
{
|
||||
size_t expected = expected_size ? *expected_size : parameter_types.size();
|
||||
Logger::Warning("Expected " + std::to_string(expected) + " attribute values, found " + std::to_string(tokens_.size()) + " for instance #" + std::to_string(name > 0 ? name : 0));
|
||||
}
|
||||
|
||||
if (tokens_.empty()) {
|
||||
return IfcEntityInstanceData(storage_t(0));
|
||||
}
|
||||
|
||||
storage_t storage(decl != nullptr
|
||||
? (std::min)(parameter_types.size(), tokens_.size())
|
||||
: tokens_.size()
|
||||
);
|
||||
|
||||
auto it = tokens_.begin();
|
||||
auto kt = parameter_types.begin();
|
||||
for (; it != tokens_.end() && ((decl == nullptr) || kt != parameter_types.end()); ++it) {
|
||||
auto& token = *it;
|
||||
// @todo coerce to expected type, e.g empty -> std::vector<int>, bool -> logical
|
||||
const IfcParse::parameter_type* param_type = nullptr;
|
||||
if (decl != nullptr) {
|
||||
param_type = *kt;
|
||||
}
|
||||
|
||||
auto index = (uint8_t) std::distance(tokens_.begin(), it);
|
||||
|
||||
boost::apply_visitor([this, &storage, name, &references_to_resolve, index, param_type](const 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)>, IfcParse::reference_or_simple_type>) {
|
||||
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 },
|
||||
v
|
||||
));
|
||||
} else {
|
||||
storage.set(index, v);
|
||||
}
|
||||
});
|
||||
} else if constexpr (std::is_same_v<std::decay_t<decltype(v)>, IfcParse::parse_context*>) {
|
||||
const auto *pt = param_type;
|
||||
if (pt) {
|
||||
while (pt->as_named_type() && pt->as_named_type()->declared_type()->as_type_declaration()) {
|
||||
pt = pt->as_named_type()->declared_type()->as_type_declaration()->declared_type();
|
||||
}
|
||||
}
|
||||
construct_<0>(*v, pt ? pt->as_aggregation_type() : nullptr, [this, &storage, name, &references_to_resolve, index](const 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 != nullptr) {
|
||||
++kt;
|
||||
}
|
||||
}
|
||||
|
||||
return IfcEntityInstanceData(std::move(storage));
|
||||
}
|
||||
+45
-22
@@ -30,6 +30,7 @@
|
||||
#include <boost/multi_index/sequenced_index.hpp>
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/variant.hpp>
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
|
||||
@@ -64,15 +65,46 @@ 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 {
|
||||
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(parse_context&&) = default;
|
||||
parse_context& operator=(parse_context&&) = default;
|
||||
|
||||
parse_context& push();
|
||||
|
||||
void push(Token t);
|
||||
|
||||
void push(IfcUtil::IfcBaseClass* inst);
|
||||
|
||||
IfcEntityInstanceData construct(int name, unresolved_references& references_to_resolve, const IfcParse::declaration* decl, boost::optional<size_t> expected_size);
|
||||
};
|
||||
|
||||
/// 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;
|
||||
typedef std::map<std::string, IfcUtil::IfcBaseClass*> entity_by_guid_t;
|
||||
typedef std::tuple<int, int, int> inverse_attr_record;
|
||||
typedef std::tuple<int, short, short> inverse_attr_record;
|
||||
enum INVERSE_ATTR {
|
||||
INSTANCE_ID,
|
||||
INSTANCE_TYPE,
|
||||
@@ -116,10 +148,6 @@ class IFC_PARSE_API IfcFile {
|
||||
}
|
||||
};
|
||||
|
||||
static bool lazy_load_;
|
||||
static bool lazy_load() { return lazy_load_; }
|
||||
static void lazy_load(bool b) { lazy_load_ = b; }
|
||||
|
||||
static bool guid_map_;
|
||||
static bool guid_map() { return guid_map_; }
|
||||
static void guid_map(bool b) { guid_map_ = b; }
|
||||
@@ -127,21 +155,20 @@ class IFC_PARSE_API IfcFile {
|
||||
private:
|
||||
typedef std::map<uint32_t, IfcUtil::IfcBaseClass*> entity_entity_map_t;
|
||||
|
||||
bool parsing_complete_;
|
||||
file_open_status good_ = file_open_status::SUCCESS;
|
||||
|
||||
const IfcParse::schema_definition* schema_;
|
||||
const IfcParse::declaration* ifcroot_type_;
|
||||
|
||||
std::vector<Argument*> internal_attribute_vector_, internal_attribute_vector_simple_type_;
|
||||
// std::vector<Argument*> internal_attribute_vector_, internal_attribute_vector_simple_type_;
|
||||
|
||||
entity_by_id_t byid_;
|
||||
// this is for simple types
|
||||
entity_by_iden_t byidentity_;
|
||||
entities_by_type_t bytype_;
|
||||
// entities_by_type_t bytype_;
|
||||
entities_by_type_t bytype_excl_;
|
||||
entities_by_ref_t byref_;
|
||||
entities_by_ref_excl_t byref_excl_;
|
||||
// entities_by_ref_t byref_;
|
||||
entities_by_ref_t byref_excl_;
|
||||
entity_by_guid_t byguid_;
|
||||
entity_entity_map_t entity_file_map_;
|
||||
|
||||
@@ -195,8 +222,8 @@ class IFC_PARSE_API IfcFile {
|
||||
type_iterator types_begin() const;
|
||||
type_iterator types_end() const;
|
||||
|
||||
type_iterator types_incl_super_begin() const;
|
||||
type_iterator types_incl_super_end() const;
|
||||
// type_iterator types_incl_super_begin() const;
|
||||
// type_iterator types_incl_super_end() const;
|
||||
|
||||
/// Returns all entities in the file that match the template argument.
|
||||
/// NOTE: This also returns subtypes of the requested type, for example:
|
||||
@@ -247,11 +274,11 @@ class IFC_PARSE_API IfcFile {
|
||||
/// Performs a depth-first traversal, returning all entity instance
|
||||
/// attributes as a flat list. NB: includes the root instance specified
|
||||
/// in the first function argument.
|
||||
aggregate_of_instance::ptr traverse(IfcUtil::IfcBaseClass* instance, int max_level = -1);
|
||||
static aggregate_of_instance::ptr traverse(IfcUtil::IfcBaseClass* instance, int max_level = -1);
|
||||
|
||||
/// Same as traverse() but maintains topological order by using a
|
||||
/// breadth-first search
|
||||
aggregate_of_instance::ptr traverse_breadth_first(IfcUtil::IfcBaseClass* instance, int max_level = -1);
|
||||
static aggregate_of_instance::ptr traverse_breadth_first(IfcUtil::IfcBaseClass* instance, int max_level = -1);
|
||||
|
||||
/// Get the attribute indices corresponding to the list of entity instances
|
||||
/// returned by getInverse().
|
||||
@@ -264,7 +291,7 @@ class IFC_PARSE_API IfcFile {
|
||||
|
||||
aggregate_of_instance::ptr getInverse(int instance_id, const IfcParse::declaration* type, int attribute_index);
|
||||
|
||||
int getTotalInverses(int instance_id);
|
||||
size_t getTotalInverses(int instance_id);
|
||||
|
||||
unsigned int FreshId() { return ++MaxId; }
|
||||
|
||||
@@ -297,11 +324,10 @@ class IFC_PARSE_API IfcFile {
|
||||
const IfcSpfHeader& header() const { return _header; }
|
||||
IfcSpfHeader& header() { return _header; }
|
||||
|
||||
std::string createTimestamp() const;
|
||||
static std::string createTimestamp() ;
|
||||
|
||||
size_t load(unsigned entity_instance_name, const IfcParse::entity* entity, Argument**& attributes, size_t num_attributes, int attribute_index = -1);
|
||||
void seek_to(const IfcEntityInstanceData& data);
|
||||
void try_read_semicolon();
|
||||
void load(unsigned entity_instance_name, const IfcParse::entity* entity, parse_context&, int attribute_index = -1);
|
||||
void try_read_semicolon() const;
|
||||
|
||||
void register_inverse(unsigned, const IfcParse::entity* from_entity, Token, int attribute_index);
|
||||
void register_inverse(unsigned, const IfcParse::entity* from_entity, IfcUtil::IfcBaseClass*, int attribute_index);
|
||||
@@ -311,9 +337,6 @@ class IFC_PARSE_API IfcFile {
|
||||
|
||||
std::pair<IfcUtil::IfcBaseClass*, double> getUnit(const std::string& unit_type);
|
||||
|
||||
bool parsing_complete() const { return parsing_complete_; }
|
||||
bool& parsing_complete() { return parsing_complete_; }
|
||||
|
||||
void build_inverses();
|
||||
|
||||
entity_by_guid_t& internal_guid_map() { return byguid_; };
|
||||
|
||||
@@ -94,7 +94,7 @@ IfcParse::IfcGlobalId::IfcGlobalId() {
|
||||
uuid_data_ = gen();
|
||||
std::vector<unsigned char> v(uuid_data_.size());
|
||||
std::copy(uuid_data_.begin(), uuid_data_.end(), v.begin());
|
||||
string_data_ = compress(&v[0]);
|
||||
string_data_ = compress(v.data());
|
||||
#if BOOST_VERSION < 104400
|
||||
formatted_string = boost::lexical_cast<std::string>(uuid_data);
|
||||
#else
|
||||
|
||||
@@ -340,21 +340,15 @@ void set_children_of_relation(Ifc4x3_add2::IfcRelAggregates* t, aggregate_of_ins
|
||||
#endif
|
||||
|
||||
IfcUtil::IfcBaseClass* get_parent_of_relation(IfcUtil::IfcBaseClass* t) {
|
||||
return *t->data().getArgument(
|
||||
t->declaration().as_entity()->attribute_index("RelatingObject"));
|
||||
return t->as<IfcUtil::IfcBaseEntity>()->get("RelatingObject");
|
||||
}
|
||||
|
||||
aggregate_of_instance::ptr get_children_of_relation(IfcUtil::IfcBaseClass* t) {
|
||||
return *t->data().getArgument(
|
||||
t->declaration().as_entity()->attribute_index("RelatedElements"));
|
||||
return t->as<IfcUtil::IfcBaseEntity>()->get("RelatedElements");
|
||||
}
|
||||
|
||||
void set_children_of_relation(IfcUtil::IfcBaseClass* t, aggregate_of_instance::ptr& cs) {
|
||||
IfcWrite::IfcWriteArgument* attr = new IfcWrite::IfcWriteArgument;
|
||||
attr->set(cs);
|
||||
t->data().setArgument(
|
||||
t->declaration().as_entity()->attribute_index("RelatedElements"),
|
||||
attr);
|
||||
return t->as<IfcUtil::IfcBaseEntity>()->set_attribute_value("RelatedElements", cs);
|
||||
}
|
||||
} // namespace
|
||||
template <typename Schema>
|
||||
@@ -440,35 +434,19 @@ class IFC_PARSE_API IfcHierarchyHelper : public IfcParse::IfcFile {
|
||||
aggregate_of_instance::ptr related_objects(new aggregate_of_instance);
|
||||
related_objects->push(related_object);
|
||||
|
||||
IfcEntityInstanceData* data = new IfcEntityInstanceData(&T::Class());
|
||||
{
|
||||
IfcWrite::IfcWriteArgument* attr = new IfcWrite::IfcWriteArgument();
|
||||
attr->set<std::string>(IfcParse::IfcGlobalId());
|
||||
data->setArgument(0, attr);
|
||||
}
|
||||
{
|
||||
IfcWrite::IfcWriteArgument* attr = new IfcWrite::IfcWriteArgument();
|
||||
attr->set(owner_hist);
|
||||
data->setArgument(1, attr);
|
||||
}
|
||||
IfcEntityInstanceData data = IfcEntityInstanceData(storage_t(T::Class().attribute_count()));
|
||||
data.storage_.set(0, (std::string)IfcParse::IfcGlobalId());
|
||||
data.storage_.set(1, owner_hist);
|
||||
int relating_index = 4;
|
||||
int related_index = 5;
|
||||
if (T::Class().name() == "IfcRelContainedInSpatialStructure" || std::is_base_of<typename Schema::IfcRelDefines, T>::value) {
|
||||
// some classes have attributes reversed.
|
||||
std::swap(relating_index, related_index);
|
||||
}
|
||||
{
|
||||
IfcWrite::IfcWriteArgument* attr = new IfcWrite::IfcWriteArgument();
|
||||
attr->set(relating_object);
|
||||
data->setArgument(relating_index, attr);
|
||||
}
|
||||
{
|
||||
IfcWrite::IfcWriteArgument* attr = new IfcWrite::IfcWriteArgument();
|
||||
attr->set(related_objects);
|
||||
data->setArgument(related_index, attr);
|
||||
}
|
||||
data.storage_.set(relating_index, relating_object);
|
||||
data.storage_.set(related_index, related_objects);
|
||||
|
||||
T* t = (T*)Schema::get_schema().instantiate(data);
|
||||
T* t = (T*)Schema::get_schema().instantiate(&T::Class(), std::move(data));
|
||||
addEntity(t);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,12 +65,14 @@ void plain_text_message(T& out, const boost::optional<const IfcUtil::IfcBaseClas
|
||||
out << "[" << severity_strings<typename T::char_type>::value[type] << "] ";
|
||||
out << "[" << get_time(type <= Logger::LOG_PERF).c_str() << "] ";
|
||||
if (current_product) {
|
||||
std::string global_id = *((IfcUtil::IfcBaseEntity*)*current_product)->get("GlobalId");
|
||||
std::string global_id = (*current_product)->as<IfcUtil::IfcBaseEntity>()->get("GlobalId");
|
||||
out << "{" << global_id.c_str() << "} ";
|
||||
}
|
||||
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()));
|
||||
@@ -141,6 +147,10 @@ void Logger::SetOutput(std::wostream* stream1, std::wostream* stream2) {
|
||||
}
|
||||
|
||||
void Logger::Message(Logger::Severity type, const std::string& message, const IfcUtil::IfcBaseInterface* instance) {
|
||||
if (type < verbosity_) {
|
||||
return;
|
||||
}
|
||||
|
||||
static std::mutex mtx;
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
|
||||
@@ -160,7 +170,7 @@ void Logger::Message(Logger::Severity type, const std::string& message, const If
|
||||
if (type > max_severity_) {
|
||||
max_severity_ = type;
|
||||
}
|
||||
if (((log2_ != nullptr) || (wlog2_ != nullptr)) && type >= verbosity_) {
|
||||
if (((log2_ != nullptr) || (wlog2_ != nullptr))) {
|
||||
if (format_ == FMT_PLAIN) {
|
||||
if (log2_ != nullptr) {
|
||||
plain_text_message(*log2_, current_product_, type, message, instance);
|
||||
|
||||
+637
-980
File diff suppressed because it is too large
Load Diff
+3
-102
@@ -148,8 +148,8 @@ Token NoneTokenPtr();
|
||||
class IFC_PARSE_API IfcSpfLexer {
|
||||
private:
|
||||
IfcCharacterDecoder* decoder_;
|
||||
unsigned int skipWhitespace();
|
||||
unsigned int skipComment();
|
||||
unsigned int skipWhitespace() const;
|
||||
unsigned int skipComment() const;
|
||||
|
||||
public:
|
||||
std::string& GetTempString() const {
|
||||
@@ -164,106 +164,7 @@ class IFC_PARSE_API IfcSpfLexer {
|
||||
void TokenString(unsigned int offset, std::string& result);
|
||||
};
|
||||
|
||||
/// Argument of type list, e.g.
|
||||
/// #1=IfcDirection((1.,0.,0.));
|
||||
/// ==========
|
||||
class IFC_PARSE_API ArgumentList : public Argument {
|
||||
private:
|
||||
size_t size_;
|
||||
Argument** list_;
|
||||
|
||||
public:
|
||||
ArgumentList() : size_(0),
|
||||
list_(0) {}
|
||||
ArgumentList(size_t n) : size_(n),
|
||||
list_(new Argument* [size_] { 0 }) {}
|
||||
~ArgumentList();
|
||||
|
||||
void read(IfcSpfLexer* lexer, std::vector<unsigned int>& ids);
|
||||
|
||||
IfcUtil::ArgumentType type() const;
|
||||
|
||||
operator std::vector<int>() const;
|
||||
operator std::vector<double>() const;
|
||||
operator std::vector<std::string>() const;
|
||||
operator std::vector<boost::dynamic_bitset<>>() const;
|
||||
operator aggregate_of_instance::ptr() const;
|
||||
|
||||
operator std::vector<std::vector<int>>() const;
|
||||
operator std::vector<std::vector<double>>() const;
|
||||
operator aggregate_of_aggregate_of_instance::ptr() const;
|
||||
|
||||
bool isNull() const;
|
||||
unsigned int size() const;
|
||||
|
||||
Argument* operator[](unsigned int index) const;
|
||||
|
||||
std::string toString(bool upper = false) const;
|
||||
|
||||
Argument**& arguments() { return list_; }
|
||||
size_t& size() { return size_; }
|
||||
};
|
||||
|
||||
/// Argument being null, e.g. '$'
|
||||
/// == ===
|
||||
class IFC_PARSE_API NullArgument : public Argument {
|
||||
public:
|
||||
NullArgument() {}
|
||||
IfcUtil::ArgumentType type() const { return IfcUtil::Argument_NULL; }
|
||||
bool isNull() const { return true; }
|
||||
unsigned int size() const { return 1; }
|
||||
Argument* operator[](unsigned int /*i*/) const { throw IfcException("Argument is not a list of attributes"); }
|
||||
std::string toString(bool /*upper=false*/) const { return "$"; }
|
||||
};
|
||||
|
||||
/// Argument of type scalar or string, e.g.
|
||||
/// #1=IfcVector(#2,1.0);
|
||||
/// == ===
|
||||
class IFC_PARSE_API TokenArgument : public Argument {
|
||||
public:
|
||||
Token token;
|
||||
TokenArgument(const Token& token);
|
||||
|
||||
IfcUtil::ArgumentType type() const;
|
||||
|
||||
operator int() const;
|
||||
operator bool() const;
|
||||
operator boost::logic::tribool() const;
|
||||
operator double() const;
|
||||
operator std::string() const;
|
||||
operator boost::dynamic_bitset<>() const;
|
||||
operator IfcUtil::IfcBaseClass*() const;
|
||||
|
||||
bool isNull() const;
|
||||
unsigned int size() const;
|
||||
|
||||
Argument* operator[](unsigned int index) const;
|
||||
std::string toString(bool upper = false) const;
|
||||
};
|
||||
|
||||
/// Argument of an IFC simple type
|
||||
/// #1=IfcTrimmedCurve(#2,(IFCPARAMETERVALUE(0.)),(IFCPARAMETERVALUE(1.)),.T.,.PARAMETER.);
|
||||
/// ===================== =====================
|
||||
class IFC_PARSE_API EntityArgument : public Argument {
|
||||
private:
|
||||
IfcUtil::IfcBaseClass* entity_;
|
||||
|
||||
public:
|
||||
EntityArgument(const Token& token);
|
||||
~EntityArgument();
|
||||
|
||||
IfcUtil::ArgumentType type() const;
|
||||
|
||||
operator IfcUtil::IfcBaseClass*() const;
|
||||
|
||||
bool isNull() const;
|
||||
unsigned int size() const;
|
||||
|
||||
Argument* operator[](unsigned int index) const;
|
||||
std::string toString(bool upper = false) const;
|
||||
};
|
||||
|
||||
IFC_PARSE_API IfcEntityInstanceData* read(unsigned int index, IfcFile* file, boost::optional<unsigned> offset = boost::none);
|
||||
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);
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ double IfcParse::get_SI_equivalent(typename Schema::IfcNamedUnit* named_unit) {
|
||||
if (component->declaration().is(Schema::IfcSIUnit::Class())) {
|
||||
si_unit = component->template as<typename Schema::IfcSIUnit>();
|
||||
typename Schema::IfcValue* value = factor->ValueComponent();
|
||||
scale = *value->data().getArgument(0);
|
||||
scale = value->data().get_attribute_value(0);
|
||||
}
|
||||
} else if (named_unit->declaration().is(Schema::IfcSIUnit::Class())) {
|
||||
si_unit = named_unit->template as<typename Schema::IfcSIUnit>();
|
||||
|
||||
@@ -152,11 +152,11 @@ IfcParse::schema_definition::~schema_definition() {
|
||||
delete factory_;
|
||||
}
|
||||
|
||||
IfcUtil::IfcBaseClass* IfcParse::schema_definition::instantiate(IfcEntityInstanceData* data) const {
|
||||
IfcUtil::IfcBaseClass* IfcParse::schema_definition::instantiate(const IfcParse::declaration* decl, IfcEntityInstanceData&& data) const {
|
||||
if (factory_ != nullptr) {
|
||||
return (*factory_)(data);
|
||||
return (*factory_)(decl, std::move(data));
|
||||
}
|
||||
return new IfcUtil::IfcLateBoundEntity(data->type(), data);
|
||||
return new IfcUtil::IfcLateBoundEntity(decl, std::move(data));
|
||||
}
|
||||
|
||||
void IfcParse::register_schema(schema_definition* schema) {
|
||||
|
||||
@@ -441,7 +441,7 @@ class IFC_PARSE_API instance_factory {
|
||||
public:
|
||||
virtual ~instance_factory() {}
|
||||
|
||||
virtual IfcUtil::IfcBaseClass* operator()(IfcEntityInstanceData* data) const = 0;
|
||||
virtual IfcUtil::IfcBaseClass* operator()(const IfcParse::declaration* decl, IfcEntityInstanceData&& data) const = 0;
|
||||
};
|
||||
|
||||
class IFC_PARSE_API schema_definition {
|
||||
@@ -507,7 +507,7 @@ class IFC_PARSE_API schema_definition {
|
||||
|
||||
const std::string& name() const { return name_; }
|
||||
|
||||
IfcUtil::IfcBaseClass* instantiate(IfcEntityInstanceData* data) const;
|
||||
IfcUtil::IfcBaseClass* instantiate(const IfcParse::declaration* decl, IfcEntityInstanceData&& data) const;
|
||||
};
|
||||
|
||||
IFC_PARSE_API const schema_definition* schema_by_name(const std::string&);
|
||||
|
||||
@@ -36,18 +36,22 @@ 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->tokens->Next();
|
||||
f->load(-1, nullptr, pc, -1);
|
||||
return pc.construct(-1, f->references_to_resolve, nullptr, s);
|
||||
}
|
||||
}
|
||||
|
||||
HeaderEntity::HeaderEntity(const char* const datatype, size_t size, IfcFile* file)
|
||||
: datatype_(datatype)
|
||||
, file_(file)
|
||||
, data_(file ? read_from_file(file, size) : IfcEntityInstanceData(storage_t(size)))
|
||||
{}
|
||||
|
||||
HeaderEntity::~HeaderEntity() {
|
||||
clearArguments();
|
||||
}
|
||||
|
||||
void IfcSpfHeader::readSemicolon() {
|
||||
@@ -89,18 +93,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() {
|
||||
|
||||
+30
-27
@@ -21,41 +21,41 @@
|
||||
#define IFCSPFHEADER_H
|
||||
|
||||
#include "ifc_parse_api.h"
|
||||
#include "IfcWrite.h"
|
||||
#include "IfcEntityInstanceData.h"
|
||||
|
||||
namespace IfcParse {
|
||||
class IfcFile;
|
||||
|
||||
class IFC_PARSE_API HeaderEntity : public IfcEntityInstanceData {
|
||||
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:
|
||||
IfcEntityInstanceData data_;
|
||||
|
||||
HeaderEntity(const char* const datatype, size_t size, IfcParse::IfcFile* file);
|
||||
virtual ~HeaderEntity();
|
||||
|
||||
void setValue(unsigned int index, const std::string& string) {
|
||||
IfcWrite::IfcWriteArgument* argument = new IfcWrite::IfcWriteArgument;
|
||||
argument->set(string);
|
||||
setArgument(index, argument);
|
||||
data_.storage_.set(index, string);
|
||||
}
|
||||
|
||||
void setValue(unsigned int index, const std::vector<std::string>& strings) {
|
||||
IfcWrite::IfcWriteArgument* argument = new IfcWrite::IfcWriteArgument;
|
||||
argument->set(strings);
|
||||
setArgument(index, argument);
|
||||
data_.storage_.set(index, strings);
|
||||
}
|
||||
|
||||
public:
|
||||
virtual size_t getArgumentCount() const {
|
||||
return size_;
|
||||
return data_.size();
|
||||
}
|
||||
|
||||
std::string toString(bool upper = false) const {
|
||||
std::stringstream stream;
|
||||
stream << datatype_ << IfcEntityInstanceData::toString(upper);
|
||||
stream << datatype_;
|
||||
data_.toString(stream, upper);
|
||||
return stream.str();
|
||||
}
|
||||
};
|
||||
@@ -64,8 +64,8 @@ class IFC_PARSE_API FileDescription : public HeaderEntity {
|
||||
public:
|
||||
explicit FileDescription(IfcFile* = 0);
|
||||
|
||||
std::vector<std::string> description() const { return *getArgument(0); }
|
||||
std::string implementation_level() const { return *getArgument(1); }
|
||||
std::vector<std::string> description() const { return data_.get_attribute_value(0); }
|
||||
std::string implementation_level() const { return data_.get_attribute_value(1); }
|
||||
|
||||
void description(const std::vector<std::string>& value) { setValue(0, value); }
|
||||
void implementation_level(const std::string& value) { setValue(1, value); }
|
||||
@@ -75,13 +75,13 @@ class IFC_PARSE_API FileName : public HeaderEntity {
|
||||
public:
|
||||
explicit FileName(IfcFile* = 0);
|
||||
|
||||
std::string name() const { return *getArgument(0); }
|
||||
std::string time_stamp() const { return *getArgument(1); }
|
||||
std::vector<std::string> author() const { return *getArgument(2); }
|
||||
std::vector<std::string> organization() const { return *getArgument(3); }
|
||||
std::string preprocessor_version() const { return *getArgument(4); }
|
||||
std::string originating_system() const { return *getArgument(5); }
|
||||
std::string authorization() const { return *getArgument(6); }
|
||||
std::string name() const { return data_.get_attribute_value(0); }
|
||||
std::string time_stamp() const { return data_.get_attribute_value(1); }
|
||||
std::vector<std::string> author() const { return data_.get_attribute_value(2); }
|
||||
std::vector<std::string> organization() const { return data_.get_attribute_value(3); }
|
||||
std::string preprocessor_version() const { return data_.get_attribute_value(4); }
|
||||
std::string originating_system() const { return data_.get_attribute_value(5); }
|
||||
std::string authorization() const { return data_.get_attribute_value(6); }
|
||||
|
||||
void name(const std::string& value) { setValue(0, value); }
|
||||
void time_stamp(const std::string& value) { setValue(1, value); }
|
||||
@@ -96,7 +96,7 @@ class IFC_PARSE_API FileSchema : public HeaderEntity {
|
||||
public:
|
||||
explicit FileSchema(IfcFile* = 0);
|
||||
|
||||
std::vector<std::string> schema_identifiers() const { return *getArgument(0); }
|
||||
std::vector<std::string> schema_identifiers() const { return data_.get_attribute_value(0); }
|
||||
|
||||
void schema_identifiers(const std::vector<std::string>& value) { setValue(0, value); }
|
||||
};
|
||||
@@ -117,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() {
|
||||
|
||||
@@ -71,9 +71,9 @@ class IFC_PARSE_API IfcSpfStream {
|
||||
/// Moves the file cursor to an arbitrary offset in the file
|
||||
void Seek(unsigned int offset);
|
||||
/// Returns the cursor position
|
||||
unsigned int Tell();
|
||||
unsigned int Tell() const;
|
||||
|
||||
bool is_eof_at(unsigned int);
|
||||
bool is_eof_at(unsigned int) const;
|
||||
void increment_at(unsigned int&);
|
||||
char peek_at(unsigned int);
|
||||
};
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "IfcBaseClass.h"
|
||||
#include "IfcException.h"
|
||||
#include "utils.h"
|
||||
#include "IfcFile.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
@@ -121,6 +122,7 @@ aggregate_of_instance::ptr aggregate_of_instance::unique() {
|
||||
return return_value;
|
||||
}
|
||||
|
||||
/*
|
||||
//Note: some of these methods are overloaded in derived classes
|
||||
Argument::operator int() const { throw IfcParse::IfcException("Argument is not an integer"); }
|
||||
Argument::operator bool() const { throw IfcParse::IfcException("Argument is not a boolean"); }
|
||||
@@ -137,6 +139,7 @@ Argument::operator aggregate_of_instance::ptr() const { throw IfcParse::IfcExcep
|
||||
Argument::operator std::vector<std::vector<int>>() const { throw IfcParse::IfcException("Argument is not a list of list of ints"); }
|
||||
Argument::operator std::vector<std::vector<double>>() const { throw IfcParse::IfcException("Argument is not a list of list of floats"); }
|
||||
Argument::operator aggregate_of_aggregate_of_instance::ptr() const { throw IfcParse::IfcException("Argument is not a list of list of entity instances"); }
|
||||
*/
|
||||
|
||||
static const char* const argument_type_string[] = {
|
||||
"NULL",
|
||||
@@ -199,16 +202,32 @@ void IfcUtil::unescape_xml(std::string& str) {
|
||||
boost::replace_all(str, ">", ">");
|
||||
}
|
||||
|
||||
/*
|
||||
Argument* IfcUtil::IfcBaseEntity::get(const std::string& name) const {
|
||||
return data().getArgument(declaration().attribute_index(name));
|
||||
}
|
||||
*/
|
||||
|
||||
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();
|
||||
for (; iter != attrs.end(); ++iter) {
|
||||
if ((*iter)->name() == name) {
|
||||
return data().getInverse(
|
||||
return file_->getInverse(
|
||||
id_,
|
||||
(*iter)->entity_reference(),
|
||||
(int)(*iter)->entity_reference()->attribute_index((*iter)->attribute_reference()));
|
||||
}
|
||||
@@ -216,10 +235,12 @@ aggregate_of_instance::ptr IfcUtil::IfcBaseEntity::get_inverse(const std::string
|
||||
throw IfcParse::IfcException(name + " not found on " + declaration().name());
|
||||
}
|
||||
|
||||
/*
|
||||
void IfcUtil::IfcBaseClass::data(IfcEntityInstanceData* data) {
|
||||
delete data_;
|
||||
data_ = data;
|
||||
}
|
||||
*/
|
||||
|
||||
IfcUtil::ArgumentType IfcUtil::make_aggregate(IfcUtil::ArgumentType elem_type) {
|
||||
switch (elem_type) {
|
||||
|
||||
@@ -1,341 +0,0 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include "IfcWrite.h"
|
||||
|
||||
#include "IfcCharacterDecoder.h"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <iomanip>
|
||||
#include <limits>
|
||||
#include <locale>
|
||||
|
||||
using namespace IfcWrite;
|
||||
|
||||
class SizeVisitor : public boost::static_visitor<int> {
|
||||
public:
|
||||
int operator()(const boost::blank& /*i*/) const { return -1; }
|
||||
int operator()(const IfcWriteArgument::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 IfcWriteArgument::empty_aggregate_t&) const { return 0; }
|
||||
int operator()(const IfcWriteArgument::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 IfcWriteArgument::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(); }
|
||||
};
|
||||
|
||||
class StringBuilderVisitor : public boost::static_visitor<void> {
|
||||
private:
|
||||
StringBuilderVisitor(const StringBuilderVisitor&); //N/A
|
||||
StringBuilderVisitor& operator=(const StringBuilderVisitor&); //N/A
|
||||
|
||||
std::ostringstream& data_;
|
||||
template <typename T>
|
||||
void serialize(const std::vector<T>& i) {
|
||||
data_ << "(";
|
||||
for (typename std::vector<T>::const_iterator it = i.begin(); it != i.end(); ++it) {
|
||||
if (it != i.begin()) {
|
||||
data_ << ",";
|
||||
}
|
||||
data_ << *it;
|
||||
}
|
||||
data_ << ")";
|
||||
}
|
||||
// The REAL token definition from the IFC SPF standard does not necessarily match
|
||||
// the output of the C++ ostream formatting operation.
|
||||
// REAL = [ SIGN ] DIGIT { DIGIT } "." { DIGIT } [ "E" [ SIGN ] DIGIT { DIGIT } ] .
|
||||
std::string format_double(const double& d) {
|
||||
std::ostringstream oss;
|
||||
oss.imbue(std::locale::classic());
|
||||
oss << std::setprecision(std::numeric_limits<double>::digits10) << d;
|
||||
const std::string str = oss.str();
|
||||
oss.str("");
|
||||
std::string::size_type e = str.find('e');
|
||||
if (e == std::string::npos) {
|
||||
e = str.find('E');
|
||||
}
|
||||
const std::string mantissa = str.substr(0, e);
|
||||
oss << mantissa;
|
||||
if (mantissa.find('.') == std::string::npos) {
|
||||
oss << ".";
|
||||
}
|
||||
if (e != std::string::npos) {
|
||||
oss << "E";
|
||||
oss << str.substr(e + 1);
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string format_binary(const boost::dynamic_bitset<>& b) {
|
||||
std::ostringstream oss;
|
||||
oss.imbue(std::locale::classic());
|
||||
oss.put('"');
|
||||
oss << std::uppercase << std::hex << std::setw(1);
|
||||
unsigned c = (unsigned)b.size();
|
||||
unsigned n = (4 - (c % 4)) & 3;
|
||||
oss << n;
|
||||
for (unsigned i = 0; i < c + n;) {
|
||||
unsigned accum = 0;
|
||||
for (int j = 0; j < 4; ++j, ++i) {
|
||||
unsigned bit = i < n ? 0 : b.test(c - i + n - 1) ? 1
|
||||
: 0;
|
||||
accum |= bit << (3 - j);
|
||||
}
|
||||
oss << accum;
|
||||
}
|
||||
oss.put('"');
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
bool upper_;
|
||||
|
||||
public:
|
||||
StringBuilderVisitor(std::ostringstream& stream, bool upper = false)
|
||||
: data_(stream),
|
||||
upper_(upper) {}
|
||||
void operator()(const boost::blank& /*i*/) { data_ << "$"; }
|
||||
void operator()(const IfcWriteArgument::Derived& /*i*/) { data_ << "*"; }
|
||||
void operator()(const int& i) { data_ << i; }
|
||||
void operator()(const bool& i) { data_ << (i ? ".T." : ".F."); }
|
||||
void operator()(const boost::logic::tribool& i) { data_ << (i ? ".T." : (boost::logic::indeterminate(i) ? ".U." : ".F.")); }
|
||||
void operator()(const double& i) { data_ << format_double(i); }
|
||||
void operator()(const boost::dynamic_bitset<>& i) { data_ << format_binary(i); }
|
||||
void operator()(const std::string& i) {
|
||||
std::string s = i;
|
||||
if (upper_) {
|
||||
data_ << static_cast<std::string>(IfcCharacterEncoder(s));
|
||||
} else {
|
||||
data_ << '\'' << s << '\'';
|
||||
}
|
||||
}
|
||||
void operator()(const std::vector<int>& i);
|
||||
void operator()(const std::vector<double>& i);
|
||||
void operator()(const std::vector<std::string>& i);
|
||||
void operator()(const std::vector<boost::dynamic_bitset<>>& i);
|
||||
void operator()(const IfcWriteArgument::EnumerationReference& i) {
|
||||
data_ << "." << i.enumeration_value << ".";
|
||||
}
|
||||
void operator()(const IfcUtil::IfcBaseClass* const& i) {
|
||||
const IfcEntityInstanceData& e = i->data();
|
||||
if (e.type()->as_entity() == nullptr) {
|
||||
data_ << e.toString(upper_);
|
||||
} else {
|
||||
data_ << "#" << e.id();
|
||||
}
|
||||
}
|
||||
void operator()(const aggregate_of_instance::ptr& i) {
|
||||
data_ << "(";
|
||||
for (aggregate_of_instance::it it = i->begin(); it != i->end(); ++it) {
|
||||
if (it != i->begin()) {
|
||||
data_ << ",";
|
||||
}
|
||||
(*this)(*it);
|
||||
}
|
||||
data_ << ")";
|
||||
}
|
||||
void operator()(const std::vector<std::vector<int>>& i);
|
||||
void operator()(const std::vector<std::vector<double>>& i);
|
||||
void operator()(const aggregate_of_aggregate_of_instance::ptr& i) {
|
||||
data_ << "(";
|
||||
for (aggregate_of_aggregate_of_instance::outer_it outer_it = i->begin(); outer_it != i->end(); ++outer_it) {
|
||||
if (outer_it != i->begin()) {
|
||||
data_ << ",";
|
||||
}
|
||||
data_ << "(";
|
||||
for (aggregate_of_aggregate_of_instance::inner_it inner_it = outer_it->begin(); inner_it != outer_it->end(); ++inner_it) {
|
||||
if (inner_it != outer_it->begin()) {
|
||||
data_ << ",";
|
||||
}
|
||||
(*this)(*inner_it);
|
||||
}
|
||||
data_ << ")";
|
||||
}
|
||||
data_ << ")";
|
||||
}
|
||||
void operator()(const IfcWriteArgument::empty_aggregate_t&) const { data_ << "()"; }
|
||||
void operator()(const IfcWriteArgument::empty_aggregate_of_aggregate_t&) const { data_ << "()"; }
|
||||
operator std::string() { return data_.str(); }
|
||||
};
|
||||
|
||||
template <>
|
||||
void StringBuilderVisitor::serialize(const std::vector<std::string>& i) {
|
||||
data_ << "(";
|
||||
for (std::vector<std::string>::const_iterator it = i.begin(); it != i.end(); ++it) {
|
||||
if (it != i.begin()) {
|
||||
data_ << ",";
|
||||
}
|
||||
std::string encoder = IfcCharacterEncoder(*it);
|
||||
data_ << encoder;
|
||||
}
|
||||
data_ << ")";
|
||||
}
|
||||
|
||||
template <>
|
||||
void StringBuilderVisitor::serialize(const std::vector<double>& i) {
|
||||
data_ << "(";
|
||||
for (std::vector<double>::const_iterator it = i.begin(); it != i.end(); ++it) {
|
||||
if (it != i.begin()) {
|
||||
data_ << ",";
|
||||
}
|
||||
data_ << format_double(*it);
|
||||
}
|
||||
data_ << ")";
|
||||
}
|
||||
|
||||
template <>
|
||||
void StringBuilderVisitor::serialize(const std::vector<boost::dynamic_bitset<>>& i) {
|
||||
data_ << "(";
|
||||
for (std::vector<boost::dynamic_bitset<>>::const_iterator it = i.begin(); it != i.end(); ++it) {
|
||||
if (it != i.begin()) {
|
||||
data_ << ",";
|
||||
}
|
||||
data_ << format_binary(*it);
|
||||
}
|
||||
data_ << ")";
|
||||
}
|
||||
|
||||
void StringBuilderVisitor::operator()(const std::vector<int>& i) { serialize(i); }
|
||||
void StringBuilderVisitor::operator()(const std::vector<double>& i) { serialize(i); }
|
||||
void StringBuilderVisitor::operator()(const std::vector<std::string>& i) { serialize(i); }
|
||||
void StringBuilderVisitor::operator()(const std::vector<boost::dynamic_bitset<>>& i) { serialize(i); }
|
||||
void StringBuilderVisitor::operator()(const std::vector<std::vector<int>>& i) {
|
||||
data_ << "(";
|
||||
for (std::vector<std::vector<int>>::const_iterator it = i.begin(); it != i.end(); ++it) {
|
||||
if (it != i.begin()) {
|
||||
data_ << ",";
|
||||
}
|
||||
serialize(*it);
|
||||
}
|
||||
data_ << ")";
|
||||
}
|
||||
void StringBuilderVisitor::operator()(const std::vector<std::vector<double>>& i) {
|
||||
data_ << "(";
|
||||
for (std::vector<std::vector<double>>::const_iterator it = i.begin(); it != i.end(); ++it) {
|
||||
if (it != i.begin()) {
|
||||
data_ << ",";
|
||||
}
|
||||
serialize(*it);
|
||||
}
|
||||
data_ << ")";
|
||||
}
|
||||
|
||||
IfcWriteArgument::operator int() const { return as<int>(); }
|
||||
IfcWriteArgument::operator bool() const { return as<bool>(); }
|
||||
IfcWriteArgument::operator boost::logic::tribool() const { return as<boost::logic::tribool>(); }
|
||||
IfcWriteArgument::operator double() const { return as<double>(); }
|
||||
IfcWriteArgument::operator std::string() const {
|
||||
if (type() == IfcUtil::Argument_ENUMERATION) {
|
||||
return as<EnumerationReference>().enumeration_value;
|
||||
}
|
||||
return as<std::string>();
|
||||
}
|
||||
IfcWriteArgument::operator IfcUtil::IfcBaseClass*() const { return as<IfcUtil::IfcBaseClass*>(); }
|
||||
IfcWriteArgument::operator boost::dynamic_bitset<>() const { return as<boost::dynamic_bitset<>>(); }
|
||||
IfcWriteArgument::operator std::vector<double>() const { return as<std::vector<double>>(); }
|
||||
IfcWriteArgument::operator std::vector<int>() const { return as<std::vector<int>>(); }
|
||||
IfcWriteArgument::operator std::vector<std::string>() const { return as<std::vector<std::string>>(); }
|
||||
IfcWriteArgument::operator std::vector<boost::dynamic_bitset<>>() const { return as<std::vector<boost::dynamic_bitset<>>>(); }
|
||||
IfcWriteArgument::operator aggregate_of_instance::ptr() const { return as<aggregate_of_instance::ptr>(); }
|
||||
IfcWriteArgument::operator std::vector<std::vector<int>>() const { return as<std::vector<std::vector<int>>>(); }
|
||||
IfcWriteArgument::operator std::vector<std::vector<double>>() const { return as<std::vector<std::vector<double>>>(); }
|
||||
IfcWriteArgument::operator aggregate_of_aggregate_of_instance::ptr() const { return as<aggregate_of_aggregate_of_instance::ptr>(); }
|
||||
bool IfcWriteArgument::isNull() const { return type() == IfcUtil::Argument_NULL; }
|
||||
Argument* IfcWriteArgument::operator[](unsigned int /*i*/) const { throw IfcParse::IfcException("Invalid cast"); }
|
||||
std::string IfcWriteArgument::toString(bool upper) const {
|
||||
std::ostringstream str;
|
||||
str.imbue(std::locale::classic());
|
||||
StringBuilderVisitor visitor(str, upper);
|
||||
container_.apply_visitor(visitor);
|
||||
return visitor;
|
||||
}
|
||||
unsigned int IfcWriteArgument::size() const {
|
||||
SizeVisitor visitor;
|
||||
const int size = container_.apply_visitor(visitor);
|
||||
if (size == -1) {
|
||||
throw IfcParse::IfcException("Invalid cast");
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
IfcUtil::ArgumentType IfcWriteArgument::type() const {
|
||||
return static_cast<IfcUtil::ArgumentType>(container_.which());
|
||||
}
|
||||
|
||||
// Overload to detect null values
|
||||
void IfcWriteArgument::set(const aggregate_of_instance::ptr& value) {
|
||||
if (value) {
|
||||
container_ = value;
|
||||
} else {
|
||||
container_ = boost::blank();
|
||||
}
|
||||
}
|
||||
|
||||
// Overload to detect null values
|
||||
void IfcWriteArgument::set(const aggregate_of_aggregate_of_instance::ptr& value) {
|
||||
if (value) {
|
||||
container_ = value;
|
||||
} else {
|
||||
container_ = boost::blank();
|
||||
}
|
||||
}
|
||||
|
||||
// Overload to detect null values
|
||||
void IfcWriteArgument::set(IfcUtil::IfcBaseInterface* const& value) {
|
||||
if (value != nullptr) {
|
||||
container_ = value->as<IfcUtil::IfcBaseClass>();
|
||||
} else {
|
||||
container_ = boost::blank();
|
||||
}
|
||||
}
|
||||
|
||||
// Overloads to raise exceptions on non-finite values
|
||||
void IfcWriteArgument::set(const double& v) {
|
||||
if (!std::isfinite(v)) {
|
||||
throw IfcParse::IfcException("Only finite values are allowed");
|
||||
}
|
||||
container_ = v;
|
||||
}
|
||||
|
||||
void IfcWriteArgument::set(const std::vector<double>& v) {
|
||||
if (std::any_of(v.begin(), v.end(), [](double v) {return !std::isfinite(v); })) {
|
||||
throw IfcParse::IfcException("Only finite values are allowed");
|
||||
}
|
||||
container_ = v;
|
||||
}
|
||||
|
||||
void IfcWriteArgument::set(const std::vector< std::vector<double> >& v) {
|
||||
if (std::any_of(v.begin(), v.end(), [](const std::vector<double>& vs) {
|
||||
return std::any_of(vs.begin(), vs.end(), [](double v) {return !std::isfinite(v); });
|
||||
})) {
|
||||
throw IfcParse::IfcException("Only finite values are allowed");
|
||||
}
|
||||
container_ = v;
|
||||
}
|
||||
|
||||
@@ -28,149 +28,4 @@
|
||||
#ifndef IFCWRITE_H
|
||||
#define IFCWRITE_H
|
||||
|
||||
#include "aggregate_of_instance.h"
|
||||
#include "ifc_parse_api.h"
|
||||
#include "IfcBaseClass.h"
|
||||
|
||||
#include <boost/dynamic_bitset.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/type_traits/is_base_of.hpp>
|
||||
#include <boost/type_traits/remove_pointer.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/variant.hpp>
|
||||
|
||||
namespace IfcWrite {
|
||||
|
||||
/// This class is a writable container for attributes. A fundamental
|
||||
/// difference with the attribute types counterparts defined in the
|
||||
/// IfcParse namespace is that this class has a Boost.Variant member
|
||||
/// for storing its value, whereas the IfcParse classes only contain
|
||||
/// lazy references to byte offsets in the IFC-SPF file.
|
||||
class IFC_PARSE_API IfcWriteArgument : public Argument {
|
||||
public:
|
||||
class EnumerationReference {
|
||||
public:
|
||||
int data;
|
||||
const char* enumeration_value;
|
||||
EnumerationReference(int data, const char* enumeration_value)
|
||||
: data(data),
|
||||
enumeration_value(enumeration_value) {}
|
||||
};
|
||||
class Derived {};
|
||||
class empty_aggregate_t {};
|
||||
class empty_aggregate_of_aggregate_t {};
|
||||
|
||||
private:
|
||||
boost::variant<
|
||||
// A null argument, it will always serialize to $
|
||||
boost::blank,
|
||||
// A derived argument, it will always serialize to *
|
||||
Derived,
|
||||
// An integer argument, e.g. 123
|
||||
|
||||
// SCALARS:
|
||||
int,
|
||||
// A boolean argument, it will serialize to either .T. or .F.
|
||||
bool,
|
||||
// A logical argument, it will serialize to either .T. or .F. or .U.
|
||||
boost::logic::tribool,
|
||||
// A floating point argument, e.g. 12.3
|
||||
double,
|
||||
// A character string argument, e.g. 'IfcOpenShell'
|
||||
std::string,
|
||||
// A binary argument, e.g. "092A" -> 100100101010
|
||||
boost::dynamic_bitset<>,
|
||||
// An enumeration argument, e.g. .USERDEFINED.
|
||||
// To initialize the argument a string representation
|
||||
// has to be explicitly passed of the enumeration value
|
||||
// which is stored internally as an integer. The argument
|
||||
// itself does not keep track of what schema enumeration
|
||||
// type is represented.
|
||||
EnumerationReference,
|
||||
// An entity instance argument. It will either serialize to
|
||||
// e.g. #123 or datatype identifier for simple types, e.g.
|
||||
// IFCREAL(12.3)
|
||||
IfcUtil::IfcBaseClass*,
|
||||
|
||||
// AGGREGATES:
|
||||
empty_aggregate_t,
|
||||
// An aggregate of integers, e.g. (1,2,3)
|
||||
std::vector<int>,
|
||||
// An aggregate of floats, e.g. (12.3,4.)
|
||||
std::vector<double>,
|
||||
// An aggregate of strings, e.g. ('Ifc','Open','Shell')
|
||||
std::vector<std::string>,
|
||||
// An aggregate of binaries, e.g. ("23B", "092A") -> (111011, 100100101010)
|
||||
std::vector<boost::dynamic_bitset<>>,
|
||||
// An aggregate of entity instances. It will either serialize to
|
||||
// e.g. (#1,#2,#3) or datatype identifier for simple types,
|
||||
// e.g. (IFCREAL(1.2),IFCINTEGER(3.))
|
||||
aggregate_of_instance::ptr,
|
||||
|
||||
// AGGREGATES OF AGGREGATES:
|
||||
empty_aggregate_of_aggregate_t,
|
||||
// An aggregate of an aggregate of ints. E.g. ((1, 2), (3))
|
||||
std::vector<std::vector<int>>,
|
||||
// An aggregate of an aggregate of floats. E.g. ((1., 2.3), (4.))
|
||||
std::vector<std::vector<double>>,
|
||||
// An aggregate of an aggregate of entities. E.g. ((#1, #2), (#3))
|
||||
aggregate_of_aggregate_of_instance::ptr>
|
||||
container_;
|
||||
|
||||
public:
|
||||
template <typename T>
|
||||
const T& as() const {
|
||||
if (const T* val = boost::get<T>(&container_)) {
|
||||
return *val;
|
||||
}
|
||||
throw IfcParse::IfcException("Invalid cast");
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename boost::disable_if<boost::is_base_of<IfcUtil::IfcBaseInterface, typename boost::remove_pointer<T>::type>, void>::type
|
||||
set(const T& type) {
|
||||
container_ = type;
|
||||
}
|
||||
|
||||
// Overload to detect null values
|
||||
void set(const aggregate_of_instance::ptr& value);
|
||||
|
||||
// Overload to detect null values
|
||||
void set(const aggregate_of_aggregate_of_instance::ptr& value);
|
||||
|
||||
// Overload to detect null values
|
||||
void set(IfcUtil::IfcBaseInterface*const & v);
|
||||
|
||||
// Overloads to raise exceptions on non-finite values
|
||||
void set(const double& v);
|
||||
void set(const std::vector<double>& v);
|
||||
void set(const std::vector< std::vector<double> >& v);
|
||||
|
||||
operator int() const;
|
||||
operator bool() const;
|
||||
operator boost::logic::tribool() const;
|
||||
operator double() const;
|
||||
operator std::string() const;
|
||||
operator boost::dynamic_bitset<>() const;
|
||||
operator IfcUtil::IfcBaseClass*() const;
|
||||
|
||||
operator std::vector<int>() const;
|
||||
operator std::vector<double>() const;
|
||||
operator std::vector<std::string>() const;
|
||||
operator std::vector<boost::dynamic_bitset<>>() const;
|
||||
operator aggregate_of_instance::ptr() const;
|
||||
|
||||
operator std::vector<std::vector<int>>() const;
|
||||
operator std::vector<std::vector<double>>() const;
|
||||
operator aggregate_of_aggregate_of_instance::ptr() const;
|
||||
|
||||
bool isNull() const;
|
||||
Argument* operator[](unsigned int index) const;
|
||||
std::string toString(bool upper = false) const;
|
||||
unsigned int size() const;
|
||||
IfcUtil::ArgumentType type() const;
|
||||
};
|
||||
|
||||
} // namespace IfcWrite
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,11 +20,19 @@
|
||||
#ifndef IFCENTITYLIST_H
|
||||
#define IFCENTITYLIST_H
|
||||
|
||||
#include "IfcBaseClass.h"
|
||||
// #include "IfcBaseClass.h"
|
||||
#include "ifc_parse_api.h"
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <set>
|
||||
|
||||
namespace IfcParse {
|
||||
class declaration;
|
||||
}
|
||||
namespace IfcUtil {
|
||||
class IfcBaseClass;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
class aggregate_of;
|
||||
|
||||
@@ -42,16 +50,10 @@ class IFC_PARSE_API aggregate_of_instance {
|
||||
unsigned int size() const;
|
||||
void reserve(unsigned capacity);
|
||||
bool contains(IfcUtil::IfcBaseClass*) const;
|
||||
|
||||
template <class U>
|
||||
typename U::list::ptr as() {
|
||||
typename U::list::ptr result(new typename U::list);
|
||||
for (it i = begin(); i != end(); ++i) {
|
||||
if ((*i)->as<U>()) {
|
||||
result->push((*i)->as<U>());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
typename U::list::ptr as();
|
||||
|
||||
void remove(IfcUtil::IfcBaseClass*);
|
||||
aggregate_of_instance::ptr filtered(const std::set<const IfcParse::declaration*>& entities);
|
||||
aggregate_of_instance::ptr unique();
|
||||
@@ -146,21 +148,10 @@ class IFC_PARSE_API aggregate_of_aggregate_of_instance {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class U>
|
||||
typename aggregate_of_aggregate_of<U>::ptr as() {
|
||||
typename aggregate_of_aggregate_of<U>::ptr result(new aggregate_of_aggregate_of<U>);
|
||||
for (outer_it outer = begin(); outer != end(); ++outer) {
|
||||
const std::vector<IfcUtil::IfcBaseClass*>& from = *outer;
|
||||
typename std::vector<U*> to;
|
||||
for (inner_it inner = from.begin(); inner != from.end(); ++inner) {
|
||||
if ((*inner)->as<U>()) {
|
||||
to.push_back((*inner)->as<U>());
|
||||
}
|
||||
}
|
||||
result->push(to);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
typename aggregate_of_aggregate_of<U>::ptr as();
|
||||
|
||||
};
|
||||
|
||||
template <class T>
|
||||
|
||||
+101
-74
@@ -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_;
|
||||
@@ -90,11 +118,11 @@ class stack_node {
|
||||
aggregate_elem_type_(nullptr) {}
|
||||
|
||||
public:
|
||||
static stack_node instance(const std::string& id_in_file, IfcUtil::IfcBaseClass* inst) {
|
||||
static stack_node instance(const std::string& id, IfcUtil::IfcBaseClass* inst) {
|
||||
stack_node node;
|
||||
node.type_ = node_instance;
|
||||
node.inst_ = inst;
|
||||
node.id_in_file_ = id_in_file;
|
||||
node.id_in_file_ = id;
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -157,7 +185,7 @@ class stack_node {
|
||||
int idx() const { return idx_; }
|
||||
const IfcParse::inverse_attribute* inv_attr() const { return inv_; }
|
||||
const std::string& tagname() const { return tagname_; }
|
||||
const std::string& id_in_file() const { return id_in_file_; }
|
||||
const std::string& id() const { return id_in_file_; }
|
||||
const IfcParse::parameter_type* aggregate_elem_type() const { return aggregate_elem_type_; }
|
||||
|
||||
std::string repr() const {
|
||||
@@ -181,7 +209,7 @@ struct ifcxml_parse_state {
|
||||
IfcParse::IfcFile* file;
|
||||
std::vector<stack_node> stack;
|
||||
std::map<std::string, int> idmap;
|
||||
std::vector<std::pair<IfcWrite::IfcWriteArgument*, std::string>> forward_references;
|
||||
std::vector<std::tuple<IfcUtil::IfcBaseEntity*, size_t, std::string>> forward_references;
|
||||
ifcxml_dialect dialect;
|
||||
};
|
||||
|
||||
@@ -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_in_file()] = 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()->set_attribute_value(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;
|
||||
}
|
||||
@@ -414,32 +442,30 @@ static void start_element(void* user, const xmlChar* tag, const xmlChar** attrs)
|
||||
// XML identifiers need to start with a alphabetic character). This convention
|
||||
// is not always followed, so a mapping is kept from XML string attribute to
|
||||
// numeric index into the IfcParse::IfcFile.
|
||||
std::string id_in_file;
|
||||
std::string id;
|
||||
|
||||
// Create an attribute value from an instance. Potentially NULL in case it is a
|
||||
// forward reference to an instance not yet encountered.
|
||||
auto instance_to_attribute = [&state](const boost::variant<std::string, IfcUtil::IfcBaseClass*>& inst_or_ref, Argument*& attr, IfcUtil::IfcBaseClass*& inst) {
|
||||
IfcWrite::IfcWriteArgument* wattr = new IfcWrite::IfcWriteArgument;
|
||||
attr = wattr;
|
||||
auto instance_to_attribute = [&state](const boost::variant<std::string, IfcUtil::IfcBaseClass*>& inst_or_ref, size_t attribute_index, IfcUtil::IfcBaseClass*& inst) {
|
||||
if (inst_or_ref.which() == 0) {
|
||||
inst = nullptr;
|
||||
// This attribute is NULL initially and after parsing the complete
|
||||
// file populated in a subsequent step.
|
||||
state->forward_references.push_back(std::make_pair((IfcWrite::IfcWriteArgument*)attr, boost::get<std::string>(inst_or_ref)));
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
// Create or reference an instance from the file and set attributes based on XML attributes.
|
||||
auto create_instance = [&state, &attributes, &id_in_file](const IfcParse::declaration* decl) {
|
||||
auto create_instance = [&state, &attributes](const IfcParse::declaration* decl) {
|
||||
boost::optional<std::string> id;
|
||||
boost::variant<std::string, IfcUtil::IfcBaseClass*> rv;
|
||||
|
||||
for (auto& pair : attributes) {
|
||||
if (pair.first == "id" || pair.first == "href" || pair.first == "ref") {
|
||||
id = id_in_file = pair.second;
|
||||
id = id = pair.second;
|
||||
if (pair.first == "href" || pair.first == "ref") {
|
||||
if (state->idmap.find(pair.second) == state->idmap.end()) {
|
||||
rv = pair.second;
|
||||
@@ -453,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() != nullptr ? decl->as_entity()->attribute_count() : 1));
|
||||
|
||||
const IfcParse::entity* entity = decl->as_entity();
|
||||
if (entity != nullptr) {
|
||||
@@ -465,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.storage_.set(idx, v);
|
||||
}, val);
|
||||
}
|
||||
} else {
|
||||
Logger::Error("Unknown attribute '" + pair.first + "' on entity '" + entity->name() + "' with value '" + pair.second + "'");
|
||||
@@ -475,14 +503,14 @@ 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, std::move(untyped));
|
||||
|
||||
if (state->dialect == ifcxml_dialect_ifc4) {
|
||||
// In IFC2X3 not added directly because attrs such as GlobalId are in
|
||||
// subsequent child nodes
|
||||
newinst = state->file->addEntity(newinst);
|
||||
if (id) {
|
||||
state->idmap[*id] = newinst->data().id();
|
||||
state->idmap[*id] = newinst->id();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -499,12 +527,12 @@ static void start_element(void* user, const xmlChar* tag, const xmlChar** attrs)
|
||||
|
||||
if (state_type == stack_node::node_select) {
|
||||
const IfcParse::declaration* decl = state->file->schema()->declaration_by_name(tagname_copy);
|
||||
Argument* attr;
|
||||
// Argument* attr;
|
||||
IfcUtil::IfcBaseClass* inst;
|
||||
auto inst_ = create_instance(decl);
|
||||
instance_to_attribute(inst_, attr, inst);
|
||||
state->stack.back().inst()->data().setArgument(state->stack.back().idx(), attr);
|
||||
state->stack.push_back(stack_node::instance(id_in_file, inst));
|
||||
instance_to_attribute(inst_, state->stack.back().idx(), inst);
|
||||
// state->stack.back().inst()->data().storage_.set(state->stack.back().idx(), attr);
|
||||
state->stack.push_back(stack_node::instance(id, inst));
|
||||
} else if (state_type == stack_node::node_aggregate) {
|
||||
|
||||
const IfcParse::parameter_type* attribute_type = state->stack.back().inst()->declaration().as_entity()->attribute_by_index(state->stack.back().idx())->type_of_attribute();
|
||||
@@ -533,10 +561,11 @@ 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);
|
||||
state->stack.push_back(stack_node::instance(id_in_file, inst));
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
} else if (state_type == stack_node::node_instance) {
|
||||
@@ -559,15 +588,12 @@ 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);
|
||||
state->stack.push_back(stack_node::instance(id_in_file, inst));
|
||||
inst->data().storage_.set(idx, state->stack.back().inst());
|
||||
state->stack.push_back(stack_node::instance(id, inst));
|
||||
} else {
|
||||
Logger::Error("Unknown attribute " + tagname);
|
||||
state->stack.push_back(state->stack.back());
|
||||
@@ -589,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_in_file, 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));
|
||||
@@ -631,28 +657,25 @@ 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) {
|
||||
// Type declaration, immediately populate attr 0
|
||||
state->stack.push_back(stack_node::instance_attribute(inst, 0));
|
||||
} else {
|
||||
state->stack.push_back(stack_node::instance(id_in_file, inst));
|
||||
state->stack.push_back(stack_node::instance(id, inst));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -667,6 +690,8 @@ end:
|
||||
|
||||
#ifdef WITH_IFCXML
|
||||
IFC_PARSE_API IfcParse::IfcFile* IfcParse::parse_ifcxml(const std::string& filename) {
|
||||
throw std::runtime_error("IFC-XML import temporarily disabled");
|
||||
|
||||
ifcxml_parse_state state;
|
||||
state.file = nullptr;
|
||||
state.dialect = ifcxml_dialect_unknown;
|
||||
@@ -680,16 +705,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();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,320 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
/*
|
||||
A dynamic sequence of variant types arranged in a way to reduce size impact due
|
||||
to alignment by grouping the 1 byte type indices. Using heap allocation - hence
|
||||
storing a pointer instead - for larger types so that the overall size of the
|
||||
variant - which is the maximum size of its constituents - is reduced.
|
||||
*/
|
||||
|
||||
#ifndef VARIANTARRAY_H
|
||||
#define VARIANTARRAY_H
|
||||
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
|
||||
#include "IfcException.h"
|
||||
|
||||
namespace impl {
|
||||
// Trait to detect unique_ptr
|
||||
template <typename...> struct is_unique_ptr : std::false_type {};
|
||||
template<class T, typename... Args>
|
||||
struct is_unique_ptr<std::unique_ptr<T, Args...>> : std::true_type {};
|
||||
|
||||
/*
|
||||
// Trait to find index of type in parameter pack
|
||||
template <typename T, typename... Ts>
|
||||
struct TypeIndex;
|
||||
template <typename T, typename... Ts>
|
||||
struct TypeIndex<T, T, Ts...> : std::integral_constant<std::size_t, 0> {};
|
||||
template <typename T, typename U, typename... Ts>
|
||||
struct TypeIndex<T, U, Ts...> : std::integral_constant<std::size_t, 1 + TypeIndex<T, Ts...>::value> {};
|
||||
template <typename T, typename... Ts>
|
||||
constexpr std::size_t TypeIndex_v = TypeIndex<T, Ts...>::value;
|
||||
*/
|
||||
|
||||
// Trait to find index of type in parameter pack considering inheritance
|
||||
template <typename T, typename... Ts>
|
||||
struct TypeIndex;
|
||||
|
||||
// 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_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>
|
||||
struct TypeIndex<T> : std::integral_constant<std::size_t, std::numeric_limits<std::size_t>::max()> {};
|
||||
|
||||
// Helper variable template
|
||||
template <typename T, typename... Ts>
|
||||
constexpr std::size_t TypeIndex_v = TypeIndex<T, Ts...>::value;
|
||||
|
||||
// Trait to determine if a type is small enough to be stored directly
|
||||
template <typename T>
|
||||
struct is_small_object {
|
||||
static constexpr bool value = sizeof(T) <= sizeof(void*) * 2;
|
||||
};
|
||||
|
||||
// Metafunction to transform T to unique_ptr<T> based on size
|
||||
template <typename T>
|
||||
struct TransformType {
|
||||
using type = typename std::conditional<
|
||||
is_small_object<T>::value,
|
||||
T,
|
||||
std::unique_ptr<T>
|
||||
>::type;
|
||||
};
|
||||
|
||||
// Helper to prepend a type to a tuple
|
||||
template <typename T, typename Tuple>
|
||||
struct TuplePrepend;
|
||||
template <typename T, typename... Types>
|
||||
struct TuplePrepend<T, std::tuple<Types...>> {
|
||||
using type = std::tuple<T, Types...>;
|
||||
};
|
||||
|
||||
// Map types based on above size transform
|
||||
template <typename... Types>
|
||||
struct MapTypes;
|
||||
template <typename FirstType, typename... RestTypes>
|
||||
struct MapTypes<FirstType, RestTypes...> {
|
||||
using type = typename TuplePrepend<
|
||||
typename TransformType<FirstType>::type,
|
||||
typename MapTypes<RestTypes...>::type
|
||||
>::type;
|
||||
};
|
||||
template <>
|
||||
struct MapTypes<> {
|
||||
using type = std::tuple<>;
|
||||
};
|
||||
template <typename... Types>
|
||||
using MapTypes_t = typename MapTypes<Types...>::type;
|
||||
|
||||
// Create aligned_union from paramater pack stored in tuple for storage in variant
|
||||
template <typename T>
|
||||
struct make_union_from_tuple {};
|
||||
template <typename... Args>
|
||||
struct make_union_from_tuple<std::tuple<Args...>> {
|
||||
using type = typename std::aligned_union<0, Args...>::type;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<typename... Types>
|
||||
class VariantArray {
|
||||
public:
|
||||
using TypesTuple = impl::MapTypes_t<Types...>;
|
||||
|
||||
VariantArray(size_t size)
|
||||
: size_and_indices_(new uint8_t[size + 1])
|
||||
, storage_(size ? new StorageType[size] : nullptr)
|
||||
{
|
||||
if (size) {
|
||||
size_and_indices_[0] = (uint8_t) size;
|
||||
memset(size_and_indices_ + 1, 0, sizeof(uint8_t) * size);
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
// type 0 needs to be default constructable
|
||||
set(i, typename std::tuple_element<0, std::tuple<Types...>>::type{});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VariantArray(VariantArray&& other) noexcept
|
||||
: size_and_indices_(other.size_and_indices_)
|
||||
, storage_(other.storage_)
|
||||
{
|
||||
other.size_and_indices_ = nullptr;
|
||||
other.storage_ = nullptr;
|
||||
}
|
||||
|
||||
VariantArray& operator=(VariantArray&& other) noexcept {
|
||||
if (this != &other) {
|
||||
free_();
|
||||
|
||||
size_and_indices_ = other.size_and_indices_;
|
||||
storage_ = other.storage_;
|
||||
|
||||
other.size_and_indices_ = nullptr;
|
||||
other.storage_ = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
VariantArray(const VariantArray&) = delete;
|
||||
VariantArray(const VariantArray&&) = delete;
|
||||
VariantArray& operator= (const VariantArray&) = delete;
|
||||
|
||||
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);
|
||||
|
||||
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 {
|
||||
new(&storage_[index]) U(std::forward<T>(value));
|
||||
}
|
||||
}
|
||||
|
||||
~VariantArray() {
|
||||
free_();
|
||||
}
|
||||
|
||||
std::size_t index(std::size_t index) const noexcept {
|
||||
return size_and_indices_[index + 1];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T& get(std::size_t index) {
|
||||
if (!has<T>(index)) {
|
||||
throw std::bad_cast();
|
||||
}
|
||||
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>
|
||||
bool has(std::size_t index) const {
|
||||
return size_and_indices_[index + 1] == impl::TypeIndex<T, Types...>::value;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const T& get(std::size_t index) const {
|
||||
if (size_and_indices_[index + 1] != impl::TypeIndex<T, Types...>::value) {
|
||||
// @todo this IfcException is silly. Figure out what
|
||||
// to do, but at the moment it is specifically caught
|
||||
// in various places.
|
||||
throw IfcParse::IfcException(
|
||||
"Type held at index " + std::to_string(index) + " is " +
|
||||
get_type_name(size_and_indices_[index + 1]) + " and not " + typeid(T).name()
|
||||
);
|
||||
}
|
||||
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>
|
||||
auto apply_visitor(Visitor&& visitor, std::size_t index) const {
|
||||
return apply_visitor_impl(std::forward<Visitor>(visitor), index, std::integral_constant<std::size_t, sizeof...(Types)>{});
|
||||
}
|
||||
|
||||
auto size() const {
|
||||
return size_and_indices_ ? size_and_indices_[0] : 0;
|
||||
}
|
||||
|
||||
private:
|
||||
using StorageType = typename impl::make_union_from_tuple<impl::MapTypes_t<Types...>>::type;
|
||||
|
||||
uint8_t* size_and_indices_;
|
||||
StorageType* storage_;
|
||||
|
||||
void destroy_at_index(std::size_t index) {
|
||||
destroy_type_at_index(index, std::integral_constant<std::size_t, sizeof...(Types)>{});
|
||||
}
|
||||
|
||||
void free_() {
|
||||
if (size_and_indices_) {
|
||||
for (std::size_t i = 0; i < size_and_indices_[0]; ++i) {
|
||||
destroy_at_index(i);
|
||||
}
|
||||
delete[] size_and_indices_;
|
||||
delete[] storage_;
|
||||
}
|
||||
}
|
||||
|
||||
template<std::size_t Index>
|
||||
void destroy_type_at_index(std::size_t index, std::integral_constant<std::size_t, Index>) {
|
||||
if (size_and_indices_[index + 1] == Index - 1) {
|
||||
using T = typename std::tuple_element_t<Index - 1, impl::MapTypes_t<Types...>>;
|
||||
if constexpr (!std::is_trivially_destructible<T>::value) {
|
||||
reinterpret_cast<T*>(&storage_[index])->~T();
|
||||
}
|
||||
size_and_indices_[index + 1] = sizeof...(Types);
|
||||
} else {
|
||||
destroy_type_at_index(index, std::integral_constant<std::size_t, Index - 1>{});
|
||||
}
|
||||
}
|
||||
|
||||
void destroy_type_at_index(std::size_t, std::integral_constant<std::size_t, 0>) {}
|
||||
|
||||
template<typename Visitor, std::size_t Index>
|
||||
auto apply_visitor_impl(Visitor&& visitor, std::size_t idx, std::integral_constant<std::size_t, Index>) const {
|
||||
if (size_and_indices_[idx + 1] == Index - 1) {
|
||||
using T = typename std::tuple_element_t<Index - 1, impl::MapTypes_t<Types...>>;
|
||||
if constexpr (impl::is_unique_ptr<T>::value) {
|
||||
return visitor(**reinterpret_cast<T*>(&storage_[idx]));
|
||||
} else {
|
||||
return visitor(*reinterpret_cast<T*>(&storage_[idx]));
|
||||
}
|
||||
}
|
||||
return apply_visitor_impl(std::forward<Visitor>(visitor), idx, std::integral_constant<std::size_t, Index - 1>{});
|
||||
}
|
||||
|
||||
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");
|
||||
if constexpr (!std::is_void_v<decltype(std::declval<Visitor>()(std::declval<typename std::tuple_element_t<0, impl::MapTypes_t<Types...>> &>()))>) {
|
||||
return decltype(std::declval<Visitor>()(std::declval<typename std::tuple_element_t<0, impl::MapTypes_t<Types...>> &>())){};
|
||||
}
|
||||
}
|
||||
|
||||
template <size_t I>
|
||||
const char* get_type_name_impl(size_t i) const {
|
||||
if constexpr (I == 0) {
|
||||
return "";
|
||||
} else {
|
||||
if (i == I - 1) {
|
||||
return typeid(std::tuple_element_t<I - 1, std::tuple<Types...>>).name();
|
||||
} else {
|
||||
return get_type_name_impl<I - 1>(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char* get_type_name(size_t i) const {
|
||||
return get_type_name_impl<sizeof...(Types)>(i);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -219,7 +219,7 @@ std::string taxonomy_item_repr(ifcopenshell::geometry::taxonomy::item::ptr i) {
|
||||
if ((ent = self->instance->as<IfcUtil::IfcBaseEntity>()) == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
return ent->data().id();
|
||||
return ent->id();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -741,7 +741,7 @@ struct ShapeRTTI : public boost::static_visitor<PyObject*>
|
||||
|
||||
template <typename Schema>
|
||||
static boost::variant<IfcGeom::Element*, IfcGeom::Representation::Representation*, IfcGeom::Transformation*> helper_fn_create_shape(const std::string& geometry_library, ifcopenshell::geometry::Settings& settings, IfcUtil::IfcBaseClass* instance, IfcUtil::IfcBaseClass* representation = 0) {
|
||||
IfcParse::IfcFile* file = instance->data().file;
|
||||
IfcParse::IfcFile* file = instance->file_;
|
||||
|
||||
ifcopenshell::geometry::Converter kernel(geometry_library, file, settings);
|
||||
|
||||
@@ -854,7 +854,7 @@ struct ShapeRTTI : public boost::static_visitor<PyObject*>
|
||||
throw IfcParse::IfcException("Failed to process shape");
|
||||
}
|
||||
|
||||
IfcGeom::Representation::BRep brep(settings, instance->declaration().name(), to_locale_invariant_string(instance->data().id()), shapes);
|
||||
IfcGeom::Representation::BRep brep(settings, instance->declaration().name(), to_locale_invariant_string(instance->as<IfcUtil::IfcBaseEntity>()->id()), shapes);
|
||||
try {
|
||||
if (settings.get<ifcopenshell::geometry::settings::IteratorOutput>().get() == ifcopenshell::geometry::settings::SERIALIZED) {
|
||||
return new IfcGeom::Representation::Serialization(brep);
|
||||
@@ -902,7 +902,7 @@ ifcopenshell::geometry::taxonomy::item::ptr try_upcast(PyObject* obj0, swig_type
|
||||
|
||||
%inline %{
|
||||
ifcopenshell::geometry::taxonomy::item::ptr map_shape(ifcopenshell::geometry::Settings& settings, IfcUtil::IfcBaseClass* instance) {
|
||||
std::unique_ptr<ifcopenshell::geometry::abstract_mapping> mapping(ifcopenshell::geometry::impl::mapping_implementations().construct(instance->data().file, settings));
|
||||
std::unique_ptr<ifcopenshell::geometry::abstract_mapping> mapping(ifcopenshell::geometry::impl::mapping_implementations().construct(instance->file_, settings));
|
||||
return mapping->map(instance);
|
||||
}
|
||||
%}
|
||||
|
||||
+90
-185
@@ -30,6 +30,8 @@ private:
|
||||
%ignore IfcParse::IfcFile::begin;
|
||||
%ignore IfcParse::IfcFile::end;
|
||||
|
||||
%ignore parse_context;
|
||||
|
||||
%ignore operator<<;
|
||||
|
||||
%ignore IfcParse::FileDescription::FileDescription;
|
||||
@@ -54,6 +56,24 @@ private:
|
||||
%rename("add") addEntity;
|
||||
%rename("remove") removeEntity;
|
||||
|
||||
%{
|
||||
|
||||
template<typename T>
|
||||
struct is_std_vector : std::false_type {};
|
||||
template<typename T, typename Alloc>
|
||||
struct is_std_vector<std::vector<T, Alloc>> : std::true_type {};
|
||||
template<typename T>
|
||||
constexpr bool is_std_vector_v = is_std_vector<T>::value;
|
||||
|
||||
template<typename T>
|
||||
struct is_std_vector_vector : std::false_type {};
|
||||
template<typename T, typename Alloc, typename Alloc2>
|
||||
struct is_std_vector_vector<std::vector<std::vector<T, Alloc>, Alloc2>> : std::true_type {};
|
||||
template<typename T>
|
||||
constexpr bool is_std_vector_vector_v = is_std_vector_vector<T>::value;
|
||||
|
||||
%}
|
||||
|
||||
class attribute_value_derived {};
|
||||
%{
|
||||
class attribute_value_derived {};
|
||||
@@ -127,15 +147,15 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
|
||||
}
|
||||
|
||||
aggregate_of_instance::ptr get_inverse(IfcUtil::IfcBaseClass* e) {
|
||||
return $self->getInverse(e->data().id(), 0, -1);
|
||||
return $self->getInverse(e->as<IfcUtil::IfcBaseEntity>()->id(), 0, -1);
|
||||
}
|
||||
|
||||
std::vector<int> get_inverse_indices(IfcUtil::IfcBaseClass* e) {
|
||||
return $self->get_inverse_indices(e->data().id());
|
||||
return $self->get_inverse_indices(e->as<IfcUtil::IfcBaseEntity>()->id());
|
||||
}
|
||||
|
||||
int get_total_inverses(IfcUtil::IfcBaseClass* e) {
|
||||
return $self->getTotalInverses(e->data().id());
|
||||
return $self->getTotalInverses(e->as<IfcUtil::IfcBaseEntity>()->id());
|
||||
}
|
||||
|
||||
void write(const std::string& fn) {
|
||||
@@ -166,6 +186,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
|
||||
return ts;
|
||||
}
|
||||
|
||||
/*
|
||||
std::vector<std::string> types_with_super() const {
|
||||
const size_t n = std::distance($self->types_incl_super_begin(), $self->types_incl_super_end());
|
||||
std::vector<std::string> ts;
|
||||
@@ -173,6 +194,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
|
||||
std::transform($self->types_incl_super_begin(), $self->types_incl_super_end(), std::back_inserter(ts), helper_fn_declaration_get_name);
|
||||
return ts;
|
||||
}
|
||||
*/
|
||||
|
||||
std::string schema_name() const {
|
||||
if ($self->schema() == 0) return "";
|
||||
@@ -220,7 +242,9 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
|
||||
// to expose it to the Python wrapper it is simply duplicated here.
|
||||
// Same applies to the two methods reimplemented below.
|
||||
int id() const {
|
||||
return $self->data().id();
|
||||
return $self->as<IfcUtil::IfcBaseEntity>() != nullptr
|
||||
? $self->as<IfcUtil::IfcBaseEntity>()->id()
|
||||
: 0;
|
||||
}
|
||||
|
||||
int __len__() const {
|
||||
@@ -279,13 +303,16 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
|
||||
return t;
|
||||
}
|
||||
|
||||
std::pair<IfcUtil::ArgumentType,Argument*> get_argument(unsigned i) {
|
||||
return std::pair<IfcUtil::ArgumentType,Argument*>($self->data().getArgument(i)->type(), $self->data().getArgument(i));
|
||||
AttributeValue get_argument(unsigned i) {
|
||||
return $self->data().get_attribute_value(i);
|
||||
}
|
||||
|
||||
std::pair<IfcUtil::ArgumentType,Argument*> get_argument(const std::string& a) {
|
||||
unsigned i = $self->declaration().as_entity()->attribute_index(a);
|
||||
return std::pair<IfcUtil::ArgumentType,Argument*>($self->data().getArgument(i)->type(), $self->data().getArgument(i));
|
||||
AttributeValue get_argument(const std::string& a) {
|
||||
auto i = $self->declaration().as_entity()->attribute_index(a);
|
||||
if (i == -1) {
|
||||
throw std::runtime_error("Attribute '" + a + "' not found on entity named " + $self->declaration().name());
|
||||
}
|
||||
return $self->data().get_attribute_value((unsigned)i);
|
||||
}
|
||||
|
||||
bool __eq__(IfcUtil::IfcBaseClass* other) const {
|
||||
@@ -293,16 +320,20 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
|
||||
}
|
||||
|
||||
std::string __repr__() const {
|
||||
return $self->data().toString();
|
||||
std::ostringstream oss;
|
||||
$self->toString(oss);
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string to_string(bool valid_spf) const {
|
||||
return $self->data().toString(valid_spf);
|
||||
std::ostringstream oss;
|
||||
$self->toString(oss, valid_spf);
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
// Just something to have a somewhat sensible value to hash
|
||||
size_t file_pointer() const {
|
||||
return reinterpret_cast<size_t>($self->data().file);
|
||||
return reinterpret_cast<size_t>($self->file_);
|
||||
}
|
||||
|
||||
unsigned get_argument_index(const std::string& a) const {
|
||||
@@ -341,7 +372,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
|
||||
void setArgumentAsNull(unsigned int i) {
|
||||
bool is_optional = $self->declaration().as_entity()->attribute_by_index(i)->optional();
|
||||
if (is_optional) {
|
||||
self->data().setArgument(i, new IfcWrite::IfcWriteArgument());
|
||||
self->set_attribute_value(i, Blank{});
|
||||
} else {
|
||||
throw IfcParse::IfcException("Attribute not set");
|
||||
}
|
||||
@@ -350,13 +381,9 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
|
||||
void setArgumentAsInt(unsigned int i, int v) {
|
||||
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
|
||||
if (arg_type == IfcUtil::Argument_INT) {
|
||||
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
|
||||
arg->set(v);
|
||||
self->data().setArgument(i, arg);
|
||||
self->set_attribute_value(i, v);
|
||||
} else if ( (arg_type == IfcUtil::Argument_BOOL) && ( (v == 0) || (v == 1) ) ) {
|
||||
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
|
||||
arg->set(v == 1);
|
||||
self->data().setArgument(i, arg);
|
||||
self->set_attribute_value(i, v);
|
||||
} else {
|
||||
throw IfcParse::IfcException("Attribute not set");
|
||||
}
|
||||
@@ -365,9 +392,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
|
||||
void setArgumentAsBool(unsigned int i, bool v) {
|
||||
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
|
||||
if (arg_type == IfcUtil::Argument_BOOL) {
|
||||
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
|
||||
arg->set(v);
|
||||
self->data().setArgument(i, arg);
|
||||
self->set_attribute_value(i, v);
|
||||
} else {
|
||||
throw IfcParse::IfcException("Attribute not set");
|
||||
}
|
||||
@@ -376,9 +401,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
|
||||
void setArgumentAsLogical(unsigned int i, boost::logic::tribool v) {
|
||||
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
|
||||
if (arg_type == IfcUtil::Argument_LOGICAL) {
|
||||
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
|
||||
arg->set(v);
|
||||
self->data().setArgument(i, arg);
|
||||
self->set_attribute_value(i, v);
|
||||
} else {
|
||||
throw IfcParse::IfcException("Attribute not set");
|
||||
}
|
||||
@@ -387,9 +410,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
|
||||
void setArgumentAsDouble(unsigned int i, double v) {
|
||||
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
|
||||
if (arg_type == IfcUtil::Argument_DOUBLE) {
|
||||
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
|
||||
arg->set(v);
|
||||
self->data().setArgument(i, arg);
|
||||
self->set_attribute_value(i, v);
|
||||
} else {
|
||||
throw IfcParse::IfcException("Attribute not set");
|
||||
}
|
||||
@@ -398,31 +419,15 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
|
||||
void setArgumentAsString(unsigned int i, const std::string& a) {
|
||||
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
|
||||
if (arg_type == IfcUtil::Argument_STRING) {
|
||||
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
|
||||
arg->set(a);
|
||||
self->data().setArgument(i, arg);
|
||||
self->set_attribute_value(i, a);
|
||||
} else if (arg_type == IfcUtil::Argument_ENUMERATION) {
|
||||
const IfcParse::enumeration_type* enum_type = $self->declaration().schema()->declaration_by_name($self->declaration().type())->as_entity()->
|
||||
attribute_by_index(i)->type_of_attribute()->as_named_type()->declared_type()->as_enumeration_type();
|
||||
|
||||
std::vector<std::string>::const_iterator it = std::find(
|
||||
enum_type->enumeration_items().begin(),
|
||||
enum_type->enumeration_items().end(),
|
||||
a);
|
||||
|
||||
if (it == enum_type->enumeration_items().end()) {
|
||||
throw IfcParse::IfcException(a + " does not name a valid item for " + enum_type->name());
|
||||
}
|
||||
|
||||
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
|
||||
arg->set(IfcWrite::IfcWriteArgument::EnumerationReference(it - enum_type->enumeration_items().begin(), it->c_str()));
|
||||
self->data().setArgument(i, arg);
|
||||
self->set_attribute_value(i, EnumerationReference(enum_type, enum_type->lookup_enum_offset(a)));
|
||||
} else if (arg_type == IfcUtil::Argument_BINARY) {
|
||||
if (IfcUtil::valid_binary_string(a)) {
|
||||
boost::dynamic_bitset<> bits(a);
|
||||
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
|
||||
arg->set(bits);
|
||||
self->data().setArgument(i, arg);
|
||||
self->set_attribute_value(i, bits);
|
||||
} else {
|
||||
throw IfcParse::IfcException("String not a valid binary representation");
|
||||
}
|
||||
@@ -434,9 +439,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
|
||||
void setArgumentAsAggregateOfInt(unsigned int i, const std::vector<int>& v) {
|
||||
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
|
||||
if (arg_type == IfcUtil::Argument_AGGREGATE_OF_INT) {
|
||||
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
|
||||
arg->set(v);
|
||||
self->data().setArgument(i, arg);
|
||||
self->set_attribute_value(i, v);
|
||||
} else {
|
||||
throw IfcParse::IfcException("Attribute not set");
|
||||
}
|
||||
@@ -445,9 +448,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
|
||||
void setArgumentAsAggregateOfDouble(unsigned int i, const std::vector<double>& v) {
|
||||
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
|
||||
if (arg_type == IfcUtil::Argument_AGGREGATE_OF_DOUBLE) {
|
||||
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
|
||||
arg->set(v);
|
||||
self->data().setArgument(i, arg);
|
||||
self->set_attribute_value(i, v);
|
||||
} else {
|
||||
throw IfcParse::IfcException("Attribute not set");
|
||||
}
|
||||
@@ -456,9 +457,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
|
||||
void setArgumentAsAggregateOfString(unsigned int i, const std::vector<std::string>& v) {
|
||||
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
|
||||
if (arg_type == IfcUtil::Argument_AGGREGATE_OF_STRING) {
|
||||
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
|
||||
arg->set(v);
|
||||
self->data().setArgument(i, arg);
|
||||
self->set_attribute_value(i, v);
|
||||
} else if (arg_type == IfcUtil::Argument_AGGREGATE_OF_BINARY) {
|
||||
std::vector< boost::dynamic_bitset<> > bits;
|
||||
bits.reserve(v.size());
|
||||
@@ -469,9 +468,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
|
||||
throw IfcParse::IfcException("String not a valid binary representation");
|
||||
}
|
||||
}
|
||||
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
|
||||
arg->set(bits);
|
||||
self->data().setArgument(i, arg);
|
||||
self->set_attribute_value(i, bits);
|
||||
} else {
|
||||
throw IfcParse::IfcException("Attribute not set");
|
||||
}
|
||||
@@ -480,9 +477,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
|
||||
void setArgumentAsEntityInstance(unsigned int i, IfcUtil::IfcBaseClass* v) {
|
||||
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
|
||||
if (arg_type == IfcUtil::Argument_ENTITY_INSTANCE) {
|
||||
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
|
||||
arg->set(v);
|
||||
self->data().setArgument(i, arg);
|
||||
self->set_attribute_value(i, v);
|
||||
} else {
|
||||
throw IfcParse::IfcException("Attribute not set");
|
||||
}
|
||||
@@ -491,9 +486,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
|
||||
void setArgumentAsAggregateOfEntityInstance(unsigned int i, aggregate_of_instance::ptr v) {
|
||||
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
|
||||
if (arg_type == IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE) {
|
||||
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
|
||||
arg->set(v);
|
||||
self->data().setArgument(i, arg);
|
||||
self->set_attribute_value(i, v);
|
||||
} else {
|
||||
throw IfcParse::IfcException("Attribute not set");
|
||||
}
|
||||
@@ -502,9 +495,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
|
||||
void setArgumentAsAggregateOfAggregateOfInt(unsigned int i, const std::vector< std::vector<int> >& v) {
|
||||
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
|
||||
if (arg_type == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT) {
|
||||
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
|
||||
arg->set(v);
|
||||
self->data().setArgument(i, arg);
|
||||
self->set_attribute_value(i, v);
|
||||
} else {
|
||||
throw IfcParse::IfcException("Attribute not set");
|
||||
}
|
||||
@@ -513,9 +504,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
|
||||
void setArgumentAsAggregateOfAggregateOfDouble(unsigned int i, const std::vector< std::vector<double> >& v) {
|
||||
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
|
||||
if (arg_type == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE) {
|
||||
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
|
||||
arg->set(v);
|
||||
self->data().setArgument(i, arg);
|
||||
self->set_attribute_value(i, v);
|
||||
} else {
|
||||
throw IfcParse::IfcException("Attribute not set");
|
||||
}
|
||||
@@ -524,9 +513,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
|
||||
void setArgumentAsAggregateOfAggregateOfEntityInstance(unsigned int i, aggregate_of_aggregate_of_instance::ptr v) {
|
||||
IfcUtil::ArgumentType arg_type = helper_fn_attribute_type($self, i);
|
||||
if (arg_type == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE) {
|
||||
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
|
||||
arg->set(v);
|
||||
self->data().setArgument(i, arg);
|
||||
self->set_attribute_value(i, v);
|
||||
} else {
|
||||
throw IfcParse::IfcException("Attribute not set");
|
||||
}
|
||||
@@ -606,27 +593,8 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
|
||||
IfcUtil::IfcBaseClass* new_IfcBaseClass(const std::string& schema_identifier, const std::string& name) {
|
||||
const IfcParse::schema_definition* schema = IfcParse::schema_by_name(schema_identifier);
|
||||
const IfcParse::declaration* decl = schema->declaration_by_name(name);
|
||||
IfcEntityInstanceData* data = new IfcEntityInstanceData(decl);
|
||||
|
||||
for (size_t i = 0; i < data->getArgumentCount(); ++i) {
|
||||
data->setArgument(i, new IfcWrite::IfcWriteArgument());
|
||||
}
|
||||
|
||||
if (decl->as_entity()) {
|
||||
const std::vector<bool>& derived = decl->as_entity()->derived();
|
||||
std::vector<bool>::const_iterator it = derived.begin();
|
||||
|
||||
size_t index = 0;
|
||||
for (; it != derived.end(); ++it, ++index) {
|
||||
if (*it) {
|
||||
IfcWrite::IfcWriteArgument* arg = new IfcWrite::IfcWriteArgument();
|
||||
arg->set(IfcWrite::IfcWriteArgument::Derived());
|
||||
data->setArgument(index, arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return schema->instantiate(data);
|
||||
IfcEntityInstanceData data(storage_t(decl->as_entity() ? decl->as_entity()->attribute_count() : 1));
|
||||
return schema->instantiate(decl, std::move(data));
|
||||
}
|
||||
%}
|
||||
|
||||
@@ -789,92 +757,29 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
|
||||
|
||||
// @todo refactor this to remove duplication with the typemap.
|
||||
// except this is calls the above function in case of instances.
|
||||
PyObject* convert_cpp_attribute_to_python(IfcUtil::ArgumentType type, Argument& arg) {
|
||||
if (!arg.isNull() && type != IfcUtil::Argument_DERIVED) {
|
||||
try {
|
||||
switch(type) {
|
||||
case IfcUtil::Argument_INT: {
|
||||
int v = arg;
|
||||
return pythonize(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_BOOL: {
|
||||
bool v = arg;
|
||||
return pythonize(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_LOGICAL: {
|
||||
boost::logic::tribool v = arg;
|
||||
return pythonize(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_DOUBLE: {
|
||||
double v = arg;
|
||||
return pythonize(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_ENUMERATION:
|
||||
case IfcUtil::Argument_STRING: {
|
||||
std::string v = arg;
|
||||
return pythonize(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_BINARY: {
|
||||
boost::dynamic_bitset<> v = arg;
|
||||
return pythonize(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_AGGREGATE_OF_INT: {
|
||||
std::vector<int> v = arg;
|
||||
PyObject* convert_cpp_attribute_to_python(AttributeValue arg) {
|
||||
return arg.array_->apply_visitor([](auto& v){
|
||||
using U = std::decay_t<decltype(v)>;
|
||||
if constexpr (is_std_vector_vector_v<U>) {
|
||||
return pythonize_vector2(v);
|
||||
} else if constexpr (is_std_vector_v<U>) {
|
||||
return pythonize_vector(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_AGGREGATE_OF_DOUBLE: {
|
||||
std::vector<double> v = arg;
|
||||
return pythonize_vector(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_AGGREGATE_OF_STRING: {
|
||||
std::vector<std::string> v = arg;
|
||||
return pythonize_vector(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_ENTITY_INSTANCE: {
|
||||
IfcUtil::IfcBaseClass* v = arg;
|
||||
return get_info_cpp(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE: {
|
||||
aggregate_of_instance::ptr v = arg;
|
||||
auto r = PyTuple_New(v->size());
|
||||
for (unsigned i = 0; i < v->size(); ++i) {
|
||||
PyTuple_SetItem(r, i, get_info_cpp((*v)[i]));
|
||||
}
|
||||
return r;
|
||||
break; }
|
||||
case IfcUtil::Argument_AGGREGATE_OF_BINARY: {
|
||||
std::vector< boost::dynamic_bitset<> > v = arg;
|
||||
return pythonize_vector(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT: {
|
||||
std::vector< std::vector<int> > v = arg;
|
||||
return pythonize_vector2(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE: {
|
||||
std::vector< std::vector<double> > v = arg;
|
||||
return pythonize_vector2(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE: {
|
||||
aggregate_of_aggregate_of_instance::ptr vs = arg;
|
||||
auto rs = PyTuple_New(vs->size());
|
||||
for (auto it = vs->begin(); it != vs->end(); ++it) {
|
||||
aggregate_of_instance::ptr v_i = arg;
|
||||
auto r = PyTuple_New(v_i->size());
|
||||
for (unsigned i = 0; i < v_i->size(); ++i) {
|
||||
PyTuple_SetItem(r, i, get_info_cpp((*v_i)[i]));
|
||||
}
|
||||
PyTuple_SetItem(rs, std::distance(vs->begin(), it), r);
|
||||
}
|
||||
return rs;
|
||||
break; }
|
||||
case IfcUtil::Argument_EMPTY_AGGREGATE: {
|
||||
return PyTuple_New(0);
|
||||
break; }
|
||||
}
|
||||
} catch(...) {}
|
||||
}
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
} else if constexpr (std::is_same_v<U, EnumerationReference>) {
|
||||
return pythonize(std::string(v.value()));
|
||||
} else if constexpr (std::is_same_v<U, Derived>) {
|
||||
if (feature_use_attribute_value_derived) {
|
||||
return SWIG_NewPointerObj(new attribute_value_derived, SWIGTYPE_p_attribute_value_derived, SWIG_POINTER_OWN);
|
||||
} else {
|
||||
Py_INCREF(Py_None);
|
||||
return static_cast<PyObject*>(Py_None);
|
||||
}
|
||||
} else if constexpr (std::is_same_v<U, empty_aggregate_t> || std::is_same_v<U, empty_aggregate_of_aggregate_t> || std::is_same_v<U, Blank>) {
|
||||
Py_INCREF(Py_None);
|
||||
return static_cast<PyObject*>(Py_None);
|
||||
} else {
|
||||
return pythonize(v);
|
||||
}
|
||||
}, arg.index_);
|
||||
}
|
||||
%}
|
||||
%inline %{
|
||||
@@ -891,8 +796,8 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
|
||||
auto attr_type = *dit
|
||||
? IfcUtil::Argument_DERIVED
|
||||
: IfcUtil::from_parameter_type((*it)->type_of_attribute());
|
||||
auto value_cpp = v->data().getArgument(std::distance(attrs.begin(), it));
|
||||
auto value_py = convert_cpp_attribute_to_python(attr_type, *value_cpp);
|
||||
auto value_cpp = v->data().get_attribute_value(std::distance(attrs.begin(), it));
|
||||
auto value_py = convert_cpp_attribute_to_python(value_cpp);
|
||||
PyDict_SetItem(d, name_py, value_py);
|
||||
Py_DECREF(name_py);
|
||||
Py_DECREF(value_py);
|
||||
@@ -900,15 +805,15 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
|
||||
|
||||
const std::string& id_cpp = "id";
|
||||
auto id_py = pythonize(id_cpp);
|
||||
auto id_v_py = pythonize(v->data().id());
|
||||
auto id_v_py = pythonize(v->as<IfcUtil::IfcBaseEntity>()->id());
|
||||
PyDict_SetItem(d, id_py, id_v_py);
|
||||
Py_DECREF(id_py);
|
||||
Py_DECREF(id_v_py);
|
||||
} else {
|
||||
const std::string& name_cpp = "wrappedValue";
|
||||
auto name_py = pythonize(name_cpp);
|
||||
auto value_cpp = v->data().getArgument(0);
|
||||
auto value_py = convert_cpp_attribute_to_python(value_cpp->type(), *value_cpp);
|
||||
auto value_cpp = v->data().get_attribute_value(0);
|
||||
auto value_py = convert_cpp_attribute_to_python(value_cpp);
|
||||
PyDict_SetItem(d, name_py, value_py);
|
||||
Py_DECREF(name_py);
|
||||
Py_DECREF(value_py);
|
||||
|
||||
@@ -31,95 +31,36 @@
|
||||
$result = SWIG_Python_str_FromChar(data_type_strings[(int)$1]);
|
||||
}
|
||||
|
||||
%typemap(out) std::pair<IfcUtil::ArgumentType, Argument*> {
|
||||
%typemap(out) AttributeValue {
|
||||
// The SWIG %exception directive does not take care
|
||||
// of our typemap. So the attribute conversion block
|
||||
// is wrapped in a try-catch block manually.
|
||||
try {
|
||||
const Argument& arg = *($1.second);
|
||||
const IfcUtil::ArgumentType type = $1.first;
|
||||
if (arg.isNull()) {
|
||||
Py_INCREF(Py_None);
|
||||
$result = Py_None;
|
||||
} else if (type == IfcUtil::Argument_DERIVED) {
|
||||
if (feature_use_attribute_value_derived) {
|
||||
$result = SWIG_NewPointerObj(new attribute_value_derived, SWIGTYPE_p_attribute_value_derived, SWIG_POINTER_OWN);
|
||||
} else {
|
||||
Py_INCREF(Py_None);
|
||||
$result = Py_None;
|
||||
}
|
||||
} else {
|
||||
switch(type) {
|
||||
case IfcUtil::Argument_INT: {
|
||||
int v = arg;
|
||||
$result = pythonize(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_BOOL: {
|
||||
bool v = arg;
|
||||
$result = pythonize(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_LOGICAL: {
|
||||
boost::logic::tribool v = arg;
|
||||
$result = pythonize(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_DOUBLE: {
|
||||
double v = arg;
|
||||
$result = pythonize(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_ENUMERATION:
|
||||
case IfcUtil::Argument_STRING: {
|
||||
std::string v = arg;
|
||||
$result = pythonize(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_BINARY: {
|
||||
boost::dynamic_bitset<> v = arg;
|
||||
$result = pythonize(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_AGGREGATE_OF_INT: {
|
||||
std::vector<int> v = arg;
|
||||
$result = pythonize_vector(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_AGGREGATE_OF_DOUBLE: {
|
||||
std::vector<double> v = arg;
|
||||
$result = pythonize_vector(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_AGGREGATE_OF_STRING: {
|
||||
std::vector<std::string> v = arg;
|
||||
$result = pythonize_vector(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_ENTITY_INSTANCE: {
|
||||
IfcUtil::IfcBaseClass* v = arg;
|
||||
$result = pythonize(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE: {
|
||||
aggregate_of_instance::ptr v = arg;
|
||||
$result = pythonize(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_AGGREGATE_OF_BINARY: {
|
||||
std::vector< boost::dynamic_bitset<> > v = arg;
|
||||
$result = pythonize_vector(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT: {
|
||||
std::vector< std::vector<int> > v = arg;
|
||||
$result = pythonize_vector2(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE: {
|
||||
std::vector< std::vector<double> > v = arg;
|
||||
$result = pythonize_vector2(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE: {
|
||||
aggregate_of_aggregate_of_instance::ptr v = arg;
|
||||
$result = pythonize(v);
|
||||
break; }
|
||||
case IfcUtil::Argument_EMPTY_AGGREGATE: {
|
||||
$result = PyTuple_New(0);
|
||||
break; }
|
||||
case IfcUtil::Argument_UNKNOWN:
|
||||
default:
|
||||
SWIG_exception(SWIG_RuntimeError,"Unknown attribute type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
$result = $1.array_->apply_visitor([](auto& v){
|
||||
using U = std::decay_t<decltype(v)>;
|
||||
if constexpr (is_std_vector_vector_v<U>) {
|
||||
return pythonize_vector2(v);
|
||||
} else if constexpr (is_std_vector_v<U>) {
|
||||
return pythonize_vector(v);
|
||||
} else if constexpr (std::is_same_v<U, EnumerationReference>) {
|
||||
return pythonize(std::string(v.value()));
|
||||
} else if constexpr (std::is_same_v<U, Derived>) {
|
||||
if (feature_use_attribute_value_derived) {
|
||||
return SWIG_NewPointerObj(new attribute_value_derived, SWIGTYPE_p_attribute_value_derived, SWIG_POINTER_OWN);
|
||||
} else {
|
||||
Py_INCREF(Py_None);
|
||||
return static_cast<PyObject*>(Py_None);
|
||||
}
|
||||
} else if constexpr (std::is_same_v<U, empty_aggregate_t> || std::is_same_v<U, empty_aggregate_of_aggregate_t> || std::is_same_v<U, Blank>) {
|
||||
Py_INCREF(Py_None);
|
||||
return static_cast<PyObject*>(Py_None);
|
||||
} else if constexpr (std::is_same_v<U, empty_aggregate_t> || std::is_same_v<U, empty_aggregate_of_aggregate_t> || std::is_same_v<U, Derived> || std::is_same_v<U, Blank>) {
|
||||
Py_INCREF(Py_None);
|
||||
return static_cast<PyObject*>(Py_None);
|
||||
} else {
|
||||
return pythonize(v);
|
||||
}
|
||||
}, $1.index_);
|
||||
} catch(IfcParse::IfcException& e) {
|
||||
SWIG_exception(SWIG_RuntimeError, e.what());
|
||||
} catch(...) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user