diff --git a/src/ifcgeomserver/IfcGeomServer.cpp b/src/ifcgeomserver/IfcGeomServer.cpp index 33ddb9b217..ed340a7a48 100644 --- a/src/ifcgeomserver/IfcGeomServer.cpp +++ b/src/ifcgeomserver/IfcGeomServer.cpp @@ -51,14 +51,8 @@ #include #include -#include -#include - #include -using namespace boost; -using boost::property_tree::ptree; - template union data_field { char buffer[sizeof(T)]; @@ -224,8 +218,40 @@ public: }; class EntityExtension { +protected: + bool trailing_, opened_; + std::stringstream json_; + + template + void put_json(const std::string& k, T v) { + if (!opened_) { + json_ << "{"; + opened_ = true; + } + if (trailing_) { + json_ << ","; + } + json_ << format_json(k) << ":" << format_json(v); + trailing_ = true; + } public: - virtual void write_contents(std::ostream& s) = 0; + EntityExtension() + : trailing_(false) + , opened_(false) + {} + + void write_contents(std::ostream& s) { + if (opened_) { + json_ << "}"; + } + + // We do a 4-byte manual alignment + std::string payload = json_.str(); + s << payload; + if (payload.size() % 4) { + s << std::string(4 - (payload.size() % 4), ' '); + } + } }; class Entity : public Command { @@ -374,40 +400,44 @@ static const std::string TOTAL_SHAPE_VOLUME = "TOTAL_SHAPE_VOLUME"; static const std::string SURFACE_AREA_ALONG_X = "SURFACE_AREA_ALONG_X"; static const std::string SURFACE_AREA_ALONG_Y = "SURFACE_AREA_ALONG_Y"; static const std::string SURFACE_AREA_ALONG_Z = "SURFACE_AREA_ALONG_Z"; +static const std::string WALKABLE_SURFACE_AREA = "WALKABLE_SURFACE_AREA"; -class QuantityWriter : public EntityExtension { +class QuantityWriter_v0 : public EntityExtension { private: const IfcGeom::BRepElement* elem_; public: - QuantityWriter(const IfcGeom::BRepElement* elem) : + QuantityWriter_v0(const IfcGeom::BRepElement* elem) : + elem_(elem) + { + put_json(TOTAL_SURFACE_AREA, 0.); + put_json(TOTAL_SHAPE_VOLUME, 0.); + if (elem_->type() == "IfcSpace") { + put_json(WALKABLE_SURFACE_AREA, 0.); + } + } +}; + +class QuantityWriter_v1 : public EntityExtension { +private: + const IfcGeom::BRepElement* elem_; +public: + QuantityWriter_v1(const IfcGeom::BRepElement* elem) : elem_(elem) - {} - void write_contents(std::ostream& s) { - ptree pt; + { double a, b, c; if (elem_->geometry().calculate_surface_area(a)) { - pt.put(TOTAL_SURFACE_AREA, a); + put_json(TOTAL_SURFACE_AREA, a); } if (elem_->geometry().calculate_volume(a)) { - pt.put(TOTAL_SHAPE_VOLUME, a); + put_json(TOTAL_SHAPE_VOLUME, a); } if (elem_->calculate_projected_surface_area(a, b, c)) { - pt.put(SURFACE_AREA_ALONG_X, a); - pt.put(SURFACE_AREA_ALONG_Y, b); - pt.put(SURFACE_AREA_ALONG_Z, c); - } - - std::ostringstream ss; - boost::property_tree::write_json(ss, pt, false); - - // We do a 4-byte manual alignment - std::string payload = ss.str(); - s << payload; - if (payload.size() % 4) { - s << std::string(4 - (payload.size() % 4), ' '); + put_json(SURFACE_AREA_ALONG_X, a); + put_json(SURFACE_AREA_ALONG_Y, b); + put_json(SURFACE_AREA_ALONG_Z, c); } } }; @@ -480,9 +510,11 @@ int main () { break; } const IfcGeom::TriangulationElement* geom = static_cast*>(iterator->get()); - std::unique_ptr eext; + std::unique_ptr eext; if (emit_quantities) { - eext.reset(new QuantityWriter(iterator->get_native())); + eext.reset(new QuantityWriter_v1(iterator->get_native())); + } else { + eext.reset(new QuantityWriter_v0(iterator->get_native())); } Entity(geom, eext.get()).write(std::cout); continue;