This commit is contained in:
Sander Boer
2019-04-26 11:22:36 +02:00
35 changed files with 1592 additions and 681 deletions
-4
View File
@@ -52,10 +52,6 @@ namespace IfcUtil {
IFC_PARSE_API const char* ArgumentTypeToString(ArgumentType argument_type);
IFC_PARSE_API bool valid_binary_string(const std::string& s);
/// Replaces spaces and potentially other problem causing characters with underscores.
IFC_PARSE_API void sanitate_material_name(std::string &str);
IFC_PARSE_API void escape_xml(std::string &str);
IFC_PARSE_API void unescape_xml(std::string &str);
}
class IFC_PARSE_API Argument {
+34 -7
View File
@@ -271,8 +271,6 @@ void InitDescriptorMap() {
current->add("wrappedValue",false,IfcUtil::Argument_DOUBLE);
current = entity_descriptor_map[Type::IfcSpecularRoughness] = new IfcEntityDescriptor(Type::IfcSpecularRoughness,0);
current->add("wrappedValue",false,IfcUtil::Argument_DOUBLE);
current = entity_descriptor_map[Type::IfcStrippedOptional] = new IfcEntityDescriptor(Type::IfcStrippedOptional,0);
current->add("wrappedValue",false,IfcUtil::Argument_BOOL);
current = entity_descriptor_map[Type::IfcTemperatureGradientMeasure] = new IfcEntityDescriptor(Type::IfcTemperatureGradientMeasure,0);
current->add("wrappedValue",false,IfcUtil::Argument_DOUBLE);
current = entity_descriptor_map[Type::IfcTemperatureRateOfChangeMeasure] = new IfcEntityDescriptor(Type::IfcTemperatureRateOfChangeMeasure,0);
@@ -1484,6 +1482,10 @@ void InitDescriptorMap() {
current->add("FilletRadius",true,IfcUtil::Argument_DOUBLE,Type::IfcNonNegativeLengthMeasure);
current->add("FlangeEdgeRadius",true,IfcUtil::Argument_DOUBLE,Type::IfcNonNegativeLengthMeasure);
current->add("FlangeSlope",true,IfcUtil::Argument_DOUBLE,Type::IfcPlaneAngleMeasure);
current = entity_descriptor_map[Type::IfcIndexedPolygonalFace] = new IfcEntityDescriptor(Type::IfcIndexedPolygonalFace,entity_descriptor_map.find(Type::IfcTessellatedItem)->second);
current->add("CoordIndex",false,IfcUtil::Argument_AGGREGATE_OF_INT,Type::IfcPositiveInteger);
current = entity_descriptor_map[Type::IfcIndexedPolygonalFaceWithVoids] = new IfcEntityDescriptor(Type::IfcIndexedPolygonalFaceWithVoids,entity_descriptor_map.find(Type::IfcIndexedPolygonalFace)->second);
current->add("InnerCoordIndices",false,IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT,Type::IfcPositiveInteger);
current = entity_descriptor_map[Type::IfcLShapeProfileDef] = new IfcEntityDescriptor(Type::IfcLShapeProfileDef,entity_descriptor_map.find(Type::IfcParameterizedProfileDef)->second);
current->add("Depth",false,IfcUtil::Argument_DOUBLE,Type::IfcPositiveLengthMeasure);
current->add("Width",true,IfcUtil::Argument_DOUBLE,Type::IfcPositiveLengthMeasure);
@@ -1766,6 +1768,8 @@ void InitDescriptorMap() {
current->add("LongName",true,IfcUtil::Argument_STRING,Type::IfcLabel);
current = entity_descriptor_map[Type::IfcSphere] = new IfcEntityDescriptor(Type::IfcSphere,entity_descriptor_map.find(Type::IfcCsgPrimitive3D)->second);
current->add("Radius",false,IfcUtil::Argument_DOUBLE,Type::IfcPositiveLengthMeasure);
current = entity_descriptor_map[Type::IfcSphericalSurface] = new IfcEntityDescriptor(Type::IfcSphericalSurface,entity_descriptor_map.find(Type::IfcElementarySurface)->second);
current->add("Radius",false,IfcUtil::Argument_DOUBLE,Type::IfcPositiveLengthMeasure);
current = entity_descriptor_map[Type::IfcStructuralActivity] = new IfcEntityDescriptor(Type::IfcStructuralActivity,entity_descriptor_map.find(Type::IfcProduct)->second);
current->add("AppliedLoad",false,IfcUtil::Argument_ENTITY_INSTANCE,Type::IfcStructuralLoad);
current->add("GlobalOrLocal",false,IfcUtil::Argument_ENUMERATION,Type::IfcGlobalOrLocalEnum);
@@ -1784,6 +1788,10 @@ void InitDescriptorMap() {
current->add("PredefinedType",false,IfcUtil::Argument_ENUMERATION,Type::IfcStructuralSurfaceActivityTypeEnum);
current = entity_descriptor_map[Type::IfcSubContractResourceType] = new IfcEntityDescriptor(Type::IfcSubContractResourceType,entity_descriptor_map.find(Type::IfcConstructionResourceType)->second);
current->add("PredefinedType",false,IfcUtil::Argument_ENUMERATION,Type::IfcSubContractResourceTypeEnum);
current = entity_descriptor_map[Type::IfcSurfaceCurve] = new IfcEntityDescriptor(Type::IfcSurfaceCurve,entity_descriptor_map.find(Type::IfcCurve)->second);
current->add("Curve3D",false,IfcUtil::Argument_ENTITY_INSTANCE,Type::IfcCurve);
current->add("AssociatedGeometry",false,IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE,Type::IfcPcurve);
current->add("MasterRepresentation",false,IfcUtil::Argument_ENUMERATION,Type::IfcPreferredSurfaceCurveRepresentation);
current = entity_descriptor_map[Type::IfcSurfaceCurveSweptAreaSolid] = new IfcEntityDescriptor(Type::IfcSurfaceCurveSweptAreaSolid,entity_descriptor_map.find(Type::IfcSweptAreaSolid)->second);
current->add("Directrix",false,IfcUtil::Argument_ENTITY_INSTANCE,Type::IfcCurve);
current->add("StartParam",true,IfcUtil::Argument_DOUBLE,Type::IfcParameterValue);
@@ -1808,13 +1816,16 @@ void InitDescriptorMap() {
current->add("WorkMethod",true,IfcUtil::Argument_STRING,Type::IfcLabel);
current = entity_descriptor_map[Type::IfcTessellatedFaceSet] = new IfcEntityDescriptor(Type::IfcTessellatedFaceSet,entity_descriptor_map.find(Type::IfcTessellatedItem)->second);
current->add("Coordinates",false,IfcUtil::Argument_ENTITY_INSTANCE,Type::IfcCartesianPointList3D);
current->add("Normals",true,IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE,Type::IfcParameterValue);
current->add("Closed",true,IfcUtil::Argument_BOOL,Type::IfcBoolean);
current = entity_descriptor_map[Type::IfcToroidalSurface] = new IfcEntityDescriptor(Type::IfcToroidalSurface,entity_descriptor_map.find(Type::IfcElementarySurface)->second);
current->add("MajorRadius",false,IfcUtil::Argument_DOUBLE,Type::IfcPositiveLengthMeasure);
current->add("MinorRadius",false,IfcUtil::Argument_DOUBLE,Type::IfcPositiveLengthMeasure);
current = entity_descriptor_map[Type::IfcTransportElementType] = new IfcEntityDescriptor(Type::IfcTransportElementType,entity_descriptor_map.find(Type::IfcElementType)->second);
current->add("PredefinedType",false,IfcUtil::Argument_ENUMERATION,Type::IfcTransportElementTypeEnum);
current = entity_descriptor_map[Type::IfcTriangulatedFaceSet] = new IfcEntityDescriptor(Type::IfcTriangulatedFaceSet,entity_descriptor_map.find(Type::IfcTessellatedFaceSet)->second);
current->add("Normals",true,IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_DOUBLE,Type::IfcParameterValue);
current->add("Closed",true,IfcUtil::Argument_BOOL,Type::IfcBoolean);
current->add("CoordIndex",false,IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT,Type::IfcPositiveInteger);
current->add("NormalIndex",true,IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_INT,Type::IfcPositiveInteger);
current->add("PnIndex",true,IfcUtil::Argument_AGGREGATE_OF_INT,Type::IfcPositiveInteger);
current = entity_descriptor_map[Type::IfcWindowLiningProperties] = new IfcEntityDescriptor(Type::IfcWindowLiningProperties,entity_descriptor_map.find(Type::IfcPreDefinedPropertySet)->second);
current->add("LiningDepth",true,IfcUtil::Argument_DOUBLE,Type::IfcPositiveLengthMeasure);
current->add("LiningThickness",true,IfcUtil::Argument_DOUBLE,Type::IfcNonNegativeLengthMeasure);
@@ -2037,6 +2048,8 @@ void InitDescriptorMap() {
current->add("SelfIntersect",true,IfcUtil::Argument_BOOL,Type::IfcBoolean);
current = entity_descriptor_map[Type::IfcInterceptorType] = new IfcEntityDescriptor(Type::IfcInterceptorType,entity_descriptor_map.find(Type::IfcFlowTreatmentDeviceType)->second);
current->add("PredefinedType",false,IfcUtil::Argument_ENUMERATION,Type::IfcInterceptorTypeEnum);
current = entity_descriptor_map[Type::IfcIntersectionCurve] = new IfcEntityDescriptor(Type::IfcIntersectionCurve,entity_descriptor_map.find(Type::IfcSurfaceCurve)->second);
current = entity_descriptor_map[Type::IfcInventory] = new IfcEntityDescriptor(Type::IfcInventory,entity_descriptor_map.find(Type::IfcGroup)->second);
current->add("PredefinedType",true,IfcUtil::Argument_ENUMERATION,Type::IfcInventoryTypeEnum);
current->add("Jurisdiction",true,IfcUtil::Argument_ENTITY_INSTANCE,Type::IfcActorSelect);
@@ -2095,6 +2108,10 @@ void InitDescriptorMap() {
current->add("PredefinedType",false,IfcUtil::Argument_ENUMERATION,Type::IfcPipeSegmentTypeEnum);
current = entity_descriptor_map[Type::IfcPlateType] = new IfcEntityDescriptor(Type::IfcPlateType,entity_descriptor_map.find(Type::IfcBuildingElementType)->second);
current->add("PredefinedType",false,IfcUtil::Argument_ENUMERATION,Type::IfcPlateTypeEnum);
current = entity_descriptor_map[Type::IfcPolygonalFaceSet] = new IfcEntityDescriptor(Type::IfcPolygonalFaceSet,entity_descriptor_map.find(Type::IfcTessellatedFaceSet)->second);
current->add("Closed",true,IfcUtil::Argument_BOOL,Type::IfcBoolean);
current->add("Faces",false,IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE,Type::IfcIndexedPolygonalFace);
current->add("PnIndex",true,IfcUtil::Argument_AGGREGATE_OF_INT,Type::IfcPositiveInteger);
current = entity_descriptor_map[Type::IfcPolyline] = new IfcEntityDescriptor(Type::IfcPolyline,entity_descriptor_map.find(Type::IfcBoundedCurve)->second);
current->add("Points",false,IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE,Type::IfcCartesianPoint);
current = entity_descriptor_map[Type::IfcPort] = new IfcEntityDescriptor(Type::IfcPort,entity_descriptor_map.find(Type::IfcProduct)->second);
@@ -2152,6 +2169,8 @@ void InitDescriptorMap() {
current->add("PredefinedType",false,IfcUtil::Argument_ENUMERATION,Type::IfcRoofTypeEnum);
current = entity_descriptor_map[Type::IfcSanitaryTerminalType] = new IfcEntityDescriptor(Type::IfcSanitaryTerminalType,entity_descriptor_map.find(Type::IfcFlowTerminalType)->second);
current->add("PredefinedType",false,IfcUtil::Argument_ENUMERATION,Type::IfcSanitaryTerminalTypeEnum);
current = entity_descriptor_map[Type::IfcSeamCurve] = new IfcEntityDescriptor(Type::IfcSeamCurve,entity_descriptor_map.find(Type::IfcSurfaceCurve)->second);
current = entity_descriptor_map[Type::IfcShadingDeviceType] = new IfcEntityDescriptor(Type::IfcShadingDeviceType,entity_descriptor_map.find(Type::IfcBuildingElementType)->second);
current->add("PredefinedType",false,IfcUtil::Argument_ENUMERATION,Type::IfcShadingDeviceTypeEnum);
current = entity_descriptor_map[Type::IfcSite] = new IfcEntityDescriptor(Type::IfcSite,entity_descriptor_map.find(Type::IfcSpatialStructureElement)->second);
@@ -2246,7 +2265,7 @@ void InitDescriptorMap() {
current->add("PredefinedType",false,IfcUtil::Argument_ENUMERATION,Type::IfcTendonTypeEnum);
current->add("NominalDiameter",true,IfcUtil::Argument_DOUBLE,Type::IfcPositiveLengthMeasure);
current->add("CrossSectionArea",true,IfcUtil::Argument_DOUBLE,Type::IfcAreaMeasure);
current->add("SheethDiameter",true,IfcUtil::Argument_DOUBLE,Type::IfcPositiveLengthMeasure);
current->add("SheathDiameter",true,IfcUtil::Argument_DOUBLE,Type::IfcPositiveLengthMeasure);
current = entity_descriptor_map[Type::IfcTransformerType] = new IfcEntityDescriptor(Type::IfcTransformerType,entity_descriptor_map.find(Type::IfcEnergyConversionDeviceType)->second);
current->add("PredefinedType",false,IfcUtil::Argument_ENUMERATION,Type::IfcTransformerTypeEnum);
current = entity_descriptor_map[Type::IfcTransportElement] = new IfcEntityDescriptor(Type::IfcTransportElement,entity_descriptor_map.find(Type::IfcElement)->second);
@@ -2904,6 +2923,7 @@ void InitDescriptorMap() {
values.push_back("ELEMENT");
values.push_back("PARTIAL");
values.push_back("PROVISIONFORVOID");
values.push_back("PROVISIONFORSPACE");
values.push_back("USERDEFINED");
values.push_back("NOTDEFINED");
enumeration_descriptor_map[Type::IfcBuildingElementProxyTypeEnum] = new IfcEnumerationDescriptor(Type::IfcBuildingElementProxyTypeEnum, values);
@@ -3548,7 +3568,7 @@ void InitDescriptorMap() {
values.push_back("EXTERNAL_WATER");
values.push_back("EXTERNAL_FIRE");
values.push_back("USERDEFINED");
values.push_back("NOTDEFIEND");
values.push_back("NOTDEFINED");
enumeration_descriptor_map[Type::IfcExternalSpatialElementTypeEnum] = new IfcEnumerationDescriptor(Type::IfcExternalSpatialElementTypeEnum, values);
values.clear(); values.reserve(128);
values.push_back("CENTRIFUGALFORWARDCURVED");
@@ -3968,6 +3988,11 @@ void InitDescriptorMap() {
values.push_back("NOTDEFINED");
enumeration_descriptor_map[Type::IfcPlateTypeEnum] = new IfcEnumerationDescriptor(Type::IfcPlateTypeEnum, values);
values.clear(); values.reserve(128);
values.push_back("CURVE3D");
values.push_back("PCURVE_S1");
values.push_back("PCURVE_S2");
enumeration_descriptor_map[Type::IfcPreferredSurfaceCurveRepresentation] = new IfcEnumerationDescriptor(Type::IfcPreferredSurfaceCurveRepresentation, values);
values.clear(); values.reserve(128);
values.push_back("ADVICE_CAUTION");
values.push_back("ADVICE_NOTE");
values.push_back("ADVICE_WARNING");
@@ -4227,6 +4252,7 @@ void InitDescriptorMap() {
values.push_back("TAPERED");
enumeration_descriptor_map[Type::IfcSectionTypeEnum] = new IfcEnumerationDescriptor(Type::IfcSectionTypeEnum, values);
values.clear(); values.reserve(128);
values.push_back("COSENSOR");
values.push_back("CO2SENSOR");
values.push_back("CONDUCTANCESENSOR");
values.push_back("CONTACTSENSOR");
@@ -4804,6 +4830,7 @@ void InitInverseMap() {
inverse_map[Type::IfcGridAxis].insert(std::make_pair("PartOfU", std::make_pair(Type::IfcGrid, 7)));
inverse_map[Type::IfcGridAxis].insert(std::make_pair("HasIntersections", std::make_pair(Type::IfcVirtualGridIntersection, 0)));
inverse_map[Type::IfcGroup].insert(std::make_pair("IsGroupedBy", std::make_pair(Type::IfcRelAssignsToGroup, 6)));
inverse_map[Type::IfcIndexedPolygonalFace].insert(std::make_pair("ToFaceSet", std::make_pair(Type::IfcPolygonalFaceSet, 2)));
inverse_map[Type::IfcLibraryInformation].insert(std::make_pair("LibraryInfoForObjects", std::make_pair(Type::IfcRelAssociatesLibrary, 5)));
inverse_map[Type::IfcLibraryInformation].insert(std::make_pair("HasLibraryReferences", std::make_pair(Type::IfcLibraryReference, 5)));
inverse_map[Type::IfcLibraryReference].insert(std::make_pair("LibraryRefForObjects", std::make_pair(Type::IfcRelAssociatesLibrary, 5)));
+138 -37
View File
File diff suppressed because one or more lines are too long
+184 -43
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -40,6 +40,7 @@ public:
it end();
IfcUtil::IfcBaseClass* operator[] (int i);
unsigned int size() const;
void reserve(unsigned capacity);
bool contains(IfcUtil::IfcBaseClass*) const;
template <class U>
typename U::list::ptr as() {
+9 -1
View File
@@ -39,6 +39,7 @@ public:
typedef boost::unordered_map<unsigned int, IfcUtil::IfcBaseClass*> entity_by_id_t;
typedef std::map<std::string, IfcSchema::IfcRoot*> entity_by_guid_t;
typedef std::map<unsigned int, std::vector<unsigned int> > entities_by_ref_t;
typedef std::map<unsigned int, IfcEntityList::ptr> ref_map_t;
typedef entity_by_id_t::const_iterator const_iterator;
class type_iterator : private entities_by_type_t::const_iterator {
@@ -62,7 +63,9 @@ public:
}
bool operator!=(const type_iterator& other) const {
return entities_by_type_t::const_iterator::operator!=(other);
const entities_by_type_t::const_iterator& self_ = *this;
const entities_by_type_t::const_iterator& other_ = other;
return self_ != other_;
}
};
@@ -75,6 +78,7 @@ private:
entities_by_type_t bytype;
entities_by_type_t bytype_excl;
entities_by_ref_t byref;
ref_map_t by_ref_cached_;
entity_by_guid_t byguid;
entity_entity_map_t entity_file_map;
@@ -144,6 +148,10 @@ public:
/// in the first function argument.
IfcEntityList::ptr traverse(IfcUtil::IfcBaseClass* instance, int max_level=-1);
/// Marks entity as modified so that potential cache for it is invalidated.
/// @todo Currently the whole cache is invalidated. Implement more fine-grained invalidation.
void mark_entity_as_modified(int id);
#ifdef USE_MMAP
bool Init(const std::string& fn, bool mmap=false);
#else
+90 -26
View File
@@ -30,35 +30,59 @@
#include <iostream>
#include <algorithm>
using boost::property_tree::ptree;
namespace {
static const char* severity_strings[] = {"Notice", "Warning", "Error"};
template <typename T>
struct severity_strings {
static const std::array<std::basic_string<T>, 3> value;
};
void plain_text_message(std::ostream& os, const boost::optional<IfcSchema::IfcProduct*>& current_product, Logger::Severity type, const std::string& message, IfcEntityInstanceData* entity) {
os << "[" << severity_strings[type] << "] ";
template <>
const std::array<std::basic_string<char>, 3> severity_strings<char>::value = { "Notice", "Warning", "Error" };
template <>
const std::array<std::basic_string<wchar_t>, 3> severity_strings<wchar_t>::value = { L"Notice", L"Warning", L"Error" };
template <typename T>
void plain_text_message(T& os, const boost::optional<IfcSchema::IfcProduct*>& current_product, Logger::Severity type, const std::string& message, IfcEntityInstanceData* entity) {
os << "[" << severity_strings<typename T::char_type>::value[type] << "] ";
if (current_product) {
os << "{" << (*current_product)->GlobalId() << "} ";
os << "{" << (*current_product)->GlobalId().c_str() << "} ";
}
os << message << std::endl;
os << message.c_str() << std::endl;
if (entity) {
std::string instance_string = entity->toString();
if (instance_string.size() > 259) {
instance_string = instance_string.substr(0, 256) + "...";
}
os << instance_string << std::endl;
os << instance_string.c_str() << std::endl;
}
}
void json_message(std::ostream& os, const boost::optional<IfcSchema::IfcProduct*>& current_product, Logger::Severity type, const std::string& message, IfcEntityInstanceData* entity) {
ptree pt;
pt.put("level", severity_strings[type]);
template <typename T>
std::basic_string<T> string_as(const std::string& s) {
std::basic_string<T> v;
v.assign(s.begin(), s.end());
return v;
}
template <typename T>
void json_message(T& os, const boost::optional<IfcSchema::IfcProduct*>& current_product, Logger::Severity type, const std::string& message, IfcEntityInstanceData* entity) {
boost::property_tree::basic_ptree<std::basic_string<typename T::char_type>, std::basic_string<typename T::char_type> > pt;
// @todo this is crazy
static const typename T::char_type level_string[] = { 'l', 'e', 'v', 'e', 'l', 0 };
static const typename T::char_type product_string[] = { 'p', 'r', 'o', 'd', 'u', 'c', 't', 0 };
static const typename T::char_type message_string[] = { 'm', 'e', 's', 's', 'a', 'g', 'e', 0 };
static const typename T::char_type instance_string[] = { 'i', 'n', 's', 't', 'a', 'n', 'c', 'e', 0 };
pt.put(level_string, severity_strings<typename T::char_type>::value[type]);
if (current_product) {
pt.put("product", (**current_product).entity->toString());
pt.put(product_string, string_as<typename T::char_type>((**current_product).entity->toString()));
}
pt.put("message", message);
pt.put(message_string, string_as<typename T::char_type>(message));
if (entity) {
pt.put("instance", entity);
pt.put(instance_string, string_as<typename T::char_type>(entity->toString()));
}
boost::property_tree::write_json(os, pt, false);
}
@@ -68,20 +92,50 @@ void Logger::SetProduct(boost::optional<IfcSchema::IfcProduct*> product) {
current_product = product;
}
void Logger::SetOutput(std::ostream* l1, std::ostream* l2) {
void Logger::SetOutput(std::ostream* l1, std::ostream* l2) {
wlog1 = wlog2 = 0;
log1 = l1;
log2 = l2;
if ( ! log2 ) {
if (!log2) {
log2 = &log_stream;
}
}
void Logger::SetOutput(std::wostream* l1, std::wostream* l2) {
log1 = log2 = 0;
wlog1 = l1;
wlog2 = l2;
if (!wlog2) {
log2 = &log_stream;
}
}
template <typename T>
void Logger::log(T& log2, Logger::Severity type, const std::string& message, IfcEntityInstanceData* entity) {
log2 << "[" << severity_strings<typename T::char_type>::value[type] << "] ";
if (current_product) {
log2 << "{" << (*current_product)->GlobalId().c_str() << "} ";
}
log2 << message.c_str() << std::endl;
if (entity) {
log2 << entity->toString().c_str() << std::endl;
}
}
void Logger::Message(Logger::Severity type, const std::string& message, IfcEntityInstanceData* entity) {
if (log2 && type >= verbosity) {
if ((log2 || wlog2) && type >= verbosity) {
if (format == FMT_PLAIN) {
plain_text_message(*log2, current_product, type, message, entity);
if (log2) {
plain_text_message(*log2, current_product, type, message, entity);
} else if (wlog2) {
plain_text_message(*wlog2, current_product, type, message, entity);
}
} else if (format == FMT_JSON) {
json_message(*log2, current_product, type, message, entity);
if (log2) {
json_message(*log2, current_product, type, message, entity);
} else if (wlog2) {
json_message(*wlog2, current_product, type, message, entity);
}
}
}
}
@@ -90,18 +144,26 @@ void Logger::Message(Logger::Severity type, const std::exception& exception, Ifc
Message(type, exception.what(), entity);
}
template <typename T>
void status(T& log1, const std::string& message, bool new_line) {
log1 << message.c_str();
if (new_line) {
log1 << std::endl;
} else {
log1 << std::flush;
}
}
void Logger::Status(const std::string& message, bool new_line) {
if (log1) {
(*log1) << message;
if ( new_line ) (*log1) << std::endl;
else (*log1) << std::flush;
status(*log1, message, new_line);
} else if (wlog1) {
status(*wlog1, message, new_line);
}
}
void Logger::ProgressBar(int progress) {
if (log1) {
Status("\r[" + std::string(progress,'#') + std::string(50 - progress,' ') + "]", false);
}
Status("\r[" + std::string(progress,'#') + std::string(50 - progress,' ') + "]", false);
}
std::string Logger::GetLog() {
@@ -116,7 +178,9 @@ Logger::Format Logger::OutputFormat() { return format; }
std::ostream* Logger::log1 = 0;
std::ostream* Logger::log2 = 0;
std::wostream* Logger::wlog1 = 0;
std::wostream* Logger::wlog2 = 0;
std::stringstream Logger::log_stream;
Logger::Severity Logger::verbosity = Logger::LOG_NOTICE;
Logger::Format Logger::format = Logger::FMT_PLAIN;
boost::optional<IfcSchema::IfcProduct*> Logger::current_product;
boost::optional<IfcSchema::IfcProduct*> Logger::current_product;
+15
View File
@@ -42,14 +42,29 @@ public:
typedef enum { LOG_NOTICE, LOG_WARNING, LOG_ERROR } Severity;
typedef enum { FMT_PLAIN, FMT_JSON } Format;
private:
// To both stream variants need to exist at runtime or should this be a
// template argument of Logger or controlled using preprocessor directives?
static std::ostream* log1;
static std::ostream* log2;
static std::wostream* wlog1;
static std::wostream* wlog2;
static std::stringstream log_stream;
static Severity verbosity;
static Format format;
static boost::optional<IfcSchema::IfcProduct*> current_product;
template <typename T>
static void log(T& log2, Logger::Severity type, const std::string& message, IfcEntityInstanceData* entity);
public:
static void SetProduct(boost::optional<IfcSchema::IfcProduct*> product);
/// Determines to what stream respectively progress and errors are logged
static void SetOutput(std::wostream* l1, std::wostream* l2);
/// Determines to what stream respectively progress and errors are logged
static void SetOutput(std::ostream* l1, std::ostream* l2);
+28 -18
View File
@@ -25,10 +25,6 @@
#include <ctime>
#include <boost/circular_buffer.hpp>
#ifdef _MSC_VER
#include <Windows.h>
#endif
#include <boost/algorithm/string.hpp>
#include <boost/math/special_functions/fpclassify.hpp>
@@ -39,6 +35,7 @@
#include "../ifcparse/IfcSpfStream.h"
#include "../ifcparse/IfcFile.h"
#include "../ifcparse/IfcSIPrefix.h"
#include "../ifcparse/utils.h"
#ifdef USE_IFC4
#include "../ifcparse/Ifc4-latebound.h"
@@ -122,9 +119,8 @@ IfcSpfStream::IfcSpfStream(const std::string& fn)
, eof(false)
{
#ifdef _MSC_VER
int fn_buffer_size = MultiByteToWideChar(CP_UTF8, 0, fn.c_str(), -1, 0, 0);
wchar_t* fn_wide = new wchar_t[fn_buffer_size];
MultiByteToWideChar(CP_UTF8, 0, fn.c_str(), -1, fn_wide, fn_buffer_size);
std::wstring fn_ws = IfcUtil::path::from_utf8(fn);
const wchar_t* fn_wide = fn_ws.c_str();
#ifdef USE_MMAP
if (mmap) {
@@ -136,7 +132,6 @@ IfcSpfStream::IfcSpfStream(const std::string& fn)
}
#endif
delete[] fn_wide;
#else
#ifdef USE_MMAP
@@ -1213,7 +1208,9 @@ void IfcEntityInstanceData::setArgument(unsigned int i, Argument* a, IfcUtil::Ar
if (this->file) {
register_inverse_visitor visitor(*this->file, *this);
apply_individual_instance_visitor(copy).apply(visitor);
}
this->file->mark_entity_as_modified(id_);
}
if (i < attributes_.size()) {
attributes_[i] = copy;
@@ -1429,6 +1426,11 @@ IfcEntityList::ptr IfcFile::traverse(IfcUtil::IfcBaseClass* instance, int max_le
return IfcParse::traverse(instance, max_level);
}
void IfcFile::mark_entity_as_modified(int /*id*/)
{
by_ref_cached_.clear();
}
void IfcFile::addEntities(IfcEntityList::ptr es) {
for( IfcEntityList::it i = es->begin(); i != es->end(); ++ i ) {
addEntity(*i);
@@ -1793,17 +1795,25 @@ IfcEntityList::ptr IfcFile::entitiesByType(const std::string& t) {
IfcEntityList::ptr IfcFile::entitiesByReference(int t) {
entities_by_ref_t::const_iterator it = byref.find(t);
IfcEntityList::ptr return_value;
IfcEntityList::ptr ret;
if (it != byref.end()) {
const std::vector<unsigned>& ids = it->second;
for (std::vector<unsigned>::const_iterator jt = ids.begin(); jt != ids.end(); ++jt) {
if (!return_value) {
return_value.reset(new IfcEntityList);
}
return_value->push(entityById(*jt));
}
ref_map_t::const_iterator cached_it = by_ref_cached_.find(t);
if (cached_it != by_ref_cached_.end()) {
ret = cached_it->second;
}
else {
if (it->second.size()) {
ret.reset(new IfcEntityList);
ret->reserve((unsigned)it->second.size());
const std::vector<unsigned>& ids = it->second;
for (std::vector<unsigned>::const_iterator jt = ids.begin(); jt != ids.end(); ++jt) {
ret->push(entityById(*jt));
}
}
by_ref_cached_[t] = ret;
}
}
return return_value;
return ret;
}
IfcUtil::IfcBaseClass* IfcFile::entityById(int id) {
+85
View File
@@ -17,8 +17,43 @@
* *
********************************************************************************/
#ifdef _MSC_VER
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#ifndef NOMINMAX
#define NOMINMAX
#endif
#ifndef NOMSG
#define NOMSG NOMSG
#endif
#ifndef NODRAWTEXT
#define NODRAWTEXT NODRAWTEXT
#endif
#ifndef NOGDI
#define NOGDI NOGDI
#endif
#ifndef NOSERVICE
#define NOSERVICE NOSERVICE
#endif
#ifndef NOKERNEL
#define NOKERNEL NOKERNEL
#endif
#ifndef NOUSER
#define NOUSER NOUSER
#endif
#ifndef NOMCX
#define NOMCX NOMCX
#endif
#ifndef NOIME
#define NOIME NOIME
#endif
#include <Windows.h>
#endif
#include "../ifcparse/IfcBaseClass.h"
#include "../ifcparse/Argument.h"
#include "../ifcparse/utils.h"
#include "../ifcparse/IfcException.h"
#include "../ifcparse/IfcEntityList.h"
@@ -48,6 +83,7 @@ void IfcEntityList::push(const IfcEntityList::ptr& l) {
}
}
unsigned int IfcEntityList::size() const { return (unsigned int) ls.size(); }
void IfcEntityList::reserve(unsigned capacity) { ls.reserve((size_t)capacity); }
IfcEntityList::it IfcEntityList::begin() { return ls.begin(); }
IfcEntityList::it IfcEntityList::end() { return ls.end(); }
IfcUtil::IfcBaseClass* IfcEntityList::operator[] (int i) {
@@ -197,3 +233,52 @@ Argument* IfcUtil::IfcBaseEntity::getArgumentByName(const std::string& name) con
unsigned int i = IfcSchema::Type::GetAttributeIndex(type(), name);
return getArgument(i);
}
#ifdef _MSC_VER
std::string IfcUtil::path::to_utf8(const std::wstring& str) {
int buffer_size = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), -1, 0, 0, 0, 0);
char* buffer = new char[buffer_size];
WideCharToMultiByte(CP_UTF8, 0, str.c_str(), -1, buffer, buffer_size, 0, 0);
std::string str_utf8(buffer);
delete[] buffer;
return str_utf8;
}
std::wstring IfcUtil::path::from_utf8(const std::string& str) {
int buffer_size = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, 0, 0);
wchar_t* buffer = new wchar_t[buffer_size];
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, buffer, buffer_size);
std::wstring str_wide(buffer);
delete[] buffer;
return str_wide;
}
IFC_PARSE_API bool IfcUtil::path::rename_file(const std::string& old_filename, const std::string& new_filename) {
std::wstring old_filename_w = from_utf8(old_filename);
std::wstring new_filename_w = from_utf8(new_filename);
delete_file(new_filename);
const bool success = !!MoveFileW(old_filename_w.c_str(), new_filename_w.c_str());
return success;
}
IFC_PARSE_API bool IfcUtil::path::delete_file(const std::string& filename) {
std::wstring filename_w = from_utf8(filename);
const bool success = !!DeleteFileW(filename_w.c_str());
return success;
}
#else
IFC_PARSE_API bool IfcUtil::path::rename_file(const std::string& old_filename, const std::string& new_filename) {
// Whether or not rename() replaces an existing file is implementation-specific,
// so remove() possible existing file always.
delete_file(new_filename);
return std::rename(old_filename.c_str(), new_filename.c_str()) == 0;
}
IFC_PARSE_API bool IfcUtil::path::delete_file(const std::string& filename) {
return std::remove(filename.c_str());
}
#endif
+59
View File
@@ -0,0 +1,59 @@
/********************************************************************************
* *
* 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 "../ifcparse/ifc_parse_api.h"
#include <string>
#ifndef IFCPARSE_UTILS_H
#define IFCPARSE_UTILS_H
namespace IfcUtil {
/// Replaces spaces and potentially other problem causing characters with underscores.
IFC_PARSE_API void sanitate_material_name(std::string &str);
IFC_PARSE_API void escape_xml(std::string &str);
IFC_PARSE_API void unescape_xml(std::string &str);
namespace path {
IFC_PARSE_API bool delete_file(const std::string& filename);
IFC_PARSE_API bool rename_file(const std::string& old_filename, const std::string& new_filename);
#ifdef _MSC_VER
/// Uses windows.h string conversion functions
IFC_PARSE_API std::string to_utf8(const std::wstring& str);
/// Uses windows.h string conversion functions
IFC_PARSE_API std::wstring from_utf8(const std::string& str);
#else
/// Identity operation
IFC_PARSE_API inline std::string to_utf8(const std::string& str) { return str; }
/// Identity operation
IFC_PARSE_API inline std::string from_utf8(const std::string& str) { return str; }
#endif
}
}
#endif