mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-26 10:11:46 +00:00
Add .ttl + Well Known Text geometry serializer
This commit is contained in:
@@ -39,6 +39,7 @@
|
|||||||
#include "../serializers/XmlSerializer.h"
|
#include "../serializers/XmlSerializer.h"
|
||||||
#include "../serializers/SvgSerializer.h"
|
#include "../serializers/SvgSerializer.h"
|
||||||
#include "../serializers/USDSerializer.h"
|
#include "../serializers/USDSerializer.h"
|
||||||
|
#include "../serializers/TtlWktSerializer.h"
|
||||||
|
|
||||||
#include "../ifcgeom/IfcGeomFilter.h"
|
#include "../ifcgeom/IfcGeomFilter.h"
|
||||||
#include "../ifcgeom/Iterator.h"
|
#include "../ifcgeom/Iterator.h"
|
||||||
@@ -132,6 +133,7 @@ void print_usage(bool suggest_help = true)
|
|||||||
#ifdef IFOPSH_WITH_CGAL
|
#ifdef IFOPSH_WITH_CGAL
|
||||||
<< " .cityjson City JSON format for geospatial data\n"
|
<< " .cityjson City JSON format for geospatial data\n"
|
||||||
#endif
|
#endif
|
||||||
|
<< " .ttl TTL/WKT RDF Turtle with Well-Known-Text geometry\n"
|
||||||
<< " .ifc IFC-SPF Industry Foundation Classes\n"
|
<< " .ifc IFC-SPF Industry Foundation Classes\n"
|
||||||
<< "\n"
|
<< "\n"
|
||||||
<< "If no output filename given, <input>" << IfcUtil::path::from_utf8(DEFAULT_EXTENSION) << " will be used as the output file.\n";
|
<< "If no output filename given, <input>" << IfcUtil::path::from_utf8(DEFAULT_EXTENSION) << " will be used as the output file.\n";
|
||||||
@@ -647,7 +649,8 @@ int main(int argc, char** argv) {
|
|||||||
IFC = IfcUtil::path::from_utf8(".ifc"),
|
IFC = IfcUtil::path::from_utf8(".ifc"),
|
||||||
USD = IfcUtil::path::from_utf8(".usd"),
|
USD = IfcUtil::path::from_utf8(".usd"),
|
||||||
USDA = IfcUtil::path::from_utf8(".usda"),
|
USDA = IfcUtil::path::from_utf8(".usda"),
|
||||||
USDC = IfcUtil::path::from_utf8(".usdc");
|
USDC = IfcUtil::path::from_utf8(".usdc"),
|
||||||
|
TTL = IfcUtil::path::from_utf8(".ttl");
|
||||||
|
|
||||||
// @todo clean up serializer selection
|
// @todo clean up serializer selection
|
||||||
// @todo detect program options that conflict with the chosen serializer
|
// @todo detect program options that conflict with the chosen serializer
|
||||||
@@ -826,6 +829,10 @@ int main(int argc, char** argv) {
|
|||||||
geometry_settings.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = true;
|
geometry_settings.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (output_extension == TTL) {
|
||||||
|
geometry_settings.get<ifcopenshell::geometry::settings::TriangulationType>().value = ifcopenshell::geometry::settings::TriangulationMethod::POLYHEDRON_WITH_HOLES;
|
||||||
|
}
|
||||||
|
|
||||||
boost::shared_ptr<GeometrySerializer> serializer; /**< @todo use std::unique_ptr when possible */
|
boost::shared_ptr<GeometrySerializer> serializer; /**< @todo use std::unique_ptr when possible */
|
||||||
if (output_extension == OBJ) {
|
if (output_extension == OBJ) {
|
||||||
// Do not use temp file for MTL as it's such a small file.
|
// Do not use temp file for MTL as it's such a small file.
|
||||||
@@ -861,6 +868,8 @@ int main(int argc, char** argv) {
|
|||||||
serializer = boost::make_shared<HdfSerializer>(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings);
|
serializer = boost::make_shared<HdfSerializer>(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
} else if (output_extension == TTL) {
|
||||||
|
serializer = boost::make_shared<TtlWktSerializer>(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings);
|
||||||
} else {
|
} else {
|
||||||
cerr_ << "[Error] Unknown output filename extension '" << output_extension << "'\n";
|
cerr_ << "[Error] Unknown output filename extension '" << output_extension << "'\n";
|
||||||
write_log(!quiet);
|
write_log(!quiet);
|
||||||
|
|||||||
@@ -570,3 +570,13 @@ class serializers:
|
|||||||
hdf5 = ifcopenshell_wrapper.HdfSerializer
|
hdf5 = ifcopenshell_wrapper.HdfSerializer
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# ttl is always available since it doesn't depend on any C++ libraries,
|
||||||
|
# just people might be using an outdated binary
|
||||||
|
if hasattr(ifcopenshell_wrapper, 'TtlWktSerializer'):
|
||||||
|
@staticmethod
|
||||||
|
def ttl(
|
||||||
|
out_filename: Union[str, serializers.buffer], geometry_settings: settings, settings: serializer_settings
|
||||||
|
) -> ifcopenshell_wrapper.SvgSerializer:
|
||||||
|
out_filename = transform_string(out_filename)
|
||||||
|
return ifcopenshell_wrapper.TtlWktSerializer(out_filename, geometry_settings, settings)
|
||||||
|
|||||||
@@ -253,6 +253,7 @@ namespace {
|
|||||||
%include "../serializers/WavefrontObjSerializer.h"
|
%include "../serializers/WavefrontObjSerializer.h"
|
||||||
%include "../serializers/XmlSerializer.h"
|
%include "../serializers/XmlSerializer.h"
|
||||||
%include "../serializers/GltfSerializer.h"
|
%include "../serializers/GltfSerializer.h"
|
||||||
|
%include "../serializers/TtlWktSerializer.h"
|
||||||
|
|
||||||
%extend ifcopenshell::geometry::taxonomy::style {
|
%extend ifcopenshell::geometry::taxonomy::style {
|
||||||
size_t instance_id() const {
|
size_t instance_id() const {
|
||||||
|
|||||||
@@ -193,6 +193,7 @@ constexpr bool is_std_vector_vector_v = is_std_vector_vector<T>::value;
|
|||||||
#include "../serializers/HdfSerializer.h"
|
#include "../serializers/HdfSerializer.h"
|
||||||
#include "../serializers/XmlSerializer.h"
|
#include "../serializers/XmlSerializer.h"
|
||||||
#include "../serializers/GltfSerializer.h"
|
#include "../serializers/GltfSerializer.h"
|
||||||
|
#include "../serializers/TtlWktSerializer.h"
|
||||||
|
|
||||||
#ifdef HAS_SCHEMA_2x3
|
#ifdef HAS_SCHEMA_2x3
|
||||||
#include "../ifcparse/Ifc2x3.h"
|
#include "../ifcparse/Ifc2x3.h"
|
||||||
|
|||||||
@@ -0,0 +1,316 @@
|
|||||||
|
/********************************************************************************
|
||||||
|
* *
|
||||||
|
* 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 "TtlWktSerializer.h"
|
||||||
|
|
||||||
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
const char* const LINESTRING = "LINESTRING";
|
||||||
|
const char* const POLYGON = "POLYGON";
|
||||||
|
|
||||||
|
void emit_polyhedral_surface(
|
||||||
|
std::ostream& os,
|
||||||
|
const std::vector<double>& vertices,
|
||||||
|
const std::vector<std::vector<std::vector<int>>>& faces)
|
||||||
|
{
|
||||||
|
os << "POLYHEDRALSURFACE Z(";
|
||||||
|
|
||||||
|
for (size_t i = 0; i < faces.size(); ++i) {
|
||||||
|
const auto& face = faces[i];
|
||||||
|
os << "(";
|
||||||
|
for (size_t j = 0; j < face.size(); ++j) {
|
||||||
|
const auto& loop = face[j];
|
||||||
|
os << "(";
|
||||||
|
for (size_t k = 0; k < loop.size(); ++k) {
|
||||||
|
int index = loop[k];
|
||||||
|
for (size_t l = 0; l < 3; ++l) {
|
||||||
|
os << vertices[index * 3 + l];
|
||||||
|
if (l != 2) {
|
||||||
|
os << " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (k < loop.size() - 1) {
|
||||||
|
os << ", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
os << ")";
|
||||||
|
if (j < face.size() - 1) {
|
||||||
|
os << ", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
os << ")";
|
||||||
|
if (i < faces.size() - 1) {
|
||||||
|
os << ",";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
os << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
void emit_line_component(
|
||||||
|
std::ostream& os,
|
||||||
|
const std::vector<double>& vertices,
|
||||||
|
const std::vector<int>& component,
|
||||||
|
bool force_2d = false,
|
||||||
|
const char* const wkt_geometry_type=LINESTRING)
|
||||||
|
{
|
||||||
|
os << wkt_geometry_type << " ";
|
||||||
|
if (!force_2d) {
|
||||||
|
os << "Z";
|
||||||
|
}
|
||||||
|
os << "(";
|
||||||
|
if (wkt_geometry_type == POLYGON) {
|
||||||
|
os << "(";
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < component.size() + (wkt_geometry_type == POLYGON ? 1 : 0); ++i) {
|
||||||
|
if (i != 0) {
|
||||||
|
os << ", ";
|
||||||
|
}
|
||||||
|
for (size_t l = 0; l < (force_2d ? 2 : 3); ++l) {
|
||||||
|
os << vertices[component[i % component.size()] * 3 + l];
|
||||||
|
if (l != (force_2d ? 1 : 2)) {
|
||||||
|
os << " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
os << ")";
|
||||||
|
if (wkt_geometry_type == POLYGON) {
|
||||||
|
os << ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void emit_line_strings(
|
||||||
|
std::ostream& os,
|
||||||
|
const std::vector<double>& vertices,
|
||||||
|
const std::vector<int>& lines,
|
||||||
|
bool force_2d = false)
|
||||||
|
{
|
||||||
|
std::unordered_map<int, std::vector<int>> adjacencyList;
|
||||||
|
std::unordered_set<int> visited;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < lines.size(); i += 2) {
|
||||||
|
for (size_t j = 0; j < 2; ++j) {
|
||||||
|
const auto& p0 = lines[i + (j ? 1 : 0)];
|
||||||
|
const auto& p1 = lines[i + (j ? 0 : 1)];
|
||||||
|
adjacencyList[p0].push_back(p1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto traverseComponent = [&](int start) {
|
||||||
|
std::vector<int> component; // To store the current component
|
||||||
|
std::queue<int> toVisit;
|
||||||
|
toVisit.push(start);
|
||||||
|
visited.insert(start);
|
||||||
|
|
||||||
|
while (!toVisit.empty()) {
|
||||||
|
int current = toVisit.front();
|
||||||
|
toVisit.pop();
|
||||||
|
component.push_back(current);
|
||||||
|
|
||||||
|
for (int neighbor : adjacencyList[current]) {
|
||||||
|
if (visited.find(neighbor) == visited.end()) {
|
||||||
|
toVisit.push(neighbor);
|
||||||
|
visited.insert(neighbor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return component;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<std::vector<int>> components;
|
||||||
|
|
||||||
|
for (auto it = lines.begin(); it != lines.end(); it += 2) {
|
||||||
|
if (visited.find(*it) == visited.end()) {
|
||||||
|
components.emplace_back(std::move(traverseComponent(*it)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (components.size() == 1) {
|
||||||
|
emit_line_component(os, vertices, components.front(), force_2d);
|
||||||
|
} else {
|
||||||
|
os << "GEOMETRYCOLLECTION(";
|
||||||
|
for (auto it = components.begin(); it != components.end(); ++it) {
|
||||||
|
if (it != components.begin()) {
|
||||||
|
os << ",";
|
||||||
|
}
|
||||||
|
emit_line_component(os, vertices, *it, force_2d);
|
||||||
|
}
|
||||||
|
os << ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string escape_for_turtle(const std::u32string& input) {
|
||||||
|
std::wostringstream escaped;
|
||||||
|
escaped << "\"";
|
||||||
|
|
||||||
|
for (auto& c : input) {
|
||||||
|
switch (c) {
|
||||||
|
case '\\':
|
||||||
|
escaped << "\\\\";
|
||||||
|
break;
|
||||||
|
case '\"':
|
||||||
|
escaped << "\\\"";
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
escaped << "\\n";
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
escaped << "\\r";
|
||||||
|
break;
|
||||||
|
case '\t':
|
||||||
|
escaped << "\\t";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (c < 0x20 || c > 0x7E) {
|
||||||
|
escaped << "\\u"
|
||||||
|
<< std::hex << std::setw(4) << std::setfill(L'0')
|
||||||
|
<< (c & 0xFFFF);
|
||||||
|
} else {
|
||||||
|
escaped.put(c);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
escaped << "\"";
|
||||||
|
return IfcUtil::convert_utf8(escaped.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Fn, typename... Ts>
|
||||||
|
std::string capture_output(Fn fn, Ts... ts) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
fn(oss, ts...);
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TtlWktSerializer::TtlWktSerializer(const stream_or_filename& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings)
|
||||||
|
: WriteOnlyGeometrySerializer(geometry_settings, settings)
|
||||||
|
, filename_(filename)
|
||||||
|
{
|
||||||
|
const auto& tri_setting = geometry_settings.get<ifcopenshell::geometry::settings::TriangulationType>().get();
|
||||||
|
if (tri_setting != ifcopenshell::geometry::settings::POLYHEDRON_WITH_HOLES) {
|
||||||
|
throw std::runtime_error("The RDF Turtle WKT serializer needs POLYHEDRON_WITH_HOLES triangulation output");
|
||||||
|
}
|
||||||
|
filename_.stream << std::setprecision(settings.get<ifcopenshell::geometry::settings::FloatingPointDigits>().get());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TtlWktSerializer::ready()
|
||||||
|
{
|
||||||
|
return filename_.is_ready();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TtlWktSerializer::writeHeader()
|
||||||
|
{
|
||||||
|
filename_.stream << "# File generated by IfcOpenShell " << IFCOPENSHELL_VERSION << "\n";
|
||||||
|
filename_.stream << "@prefix geo: <http://www.opengis.net/ont/geosparql#> .\n";
|
||||||
|
filename_.stream << "@prefix ex: <http://example.org/> .\n";
|
||||||
|
filename_.stream << "@prefix dcterms: <http://purl.org/dc/terms/> .\n";
|
||||||
|
filename_.stream << "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void TtlWktSerializer::write(const IfcGeom::TriangulationElement* o)
|
||||||
|
{
|
||||||
|
auto ttl_object_id = [&]() {
|
||||||
|
return boost::replace_all_copy(object_id(o), "-", "_");
|
||||||
|
};
|
||||||
|
|
||||||
|
filename_.stream << "ex:" << ttl_object_id() << " a geo:Feature ;\n";
|
||||||
|
filename_.stream << " dcterms:identifier " << escape_for_turtle(
|
||||||
|
IfcUtil::convert_utf8_to_utf32(o->guid())) << " ;\n";
|
||||||
|
filename_.stream << " rdfs:label " << escape_for_turtle(
|
||||||
|
IfcUtil::convert_utf8_to_utf32(o->name())
|
||||||
|
) << " ;\n";
|
||||||
|
filename_.stream << " geo:hasGeometry ex:" << ttl_object_id() << "_geometry .\n\n";
|
||||||
|
|
||||||
|
if (!o->geometry().polyhedral_faces_with_holes().empty()) {
|
||||||
|
filename_.stream << "ex:" << ttl_object_id() << "_geometry a geo:Geometry ;\n";
|
||||||
|
filename_.stream << " geo:asWKT " << escape_for_turtle(
|
||||||
|
IfcUtil::convert_utf8_to_utf32(
|
||||||
|
capture_output(
|
||||||
|
emit_polyhedral_surface,
|
||||||
|
o->geometry().verts(),
|
||||||
|
o->geometry().polyhedral_faces_with_holes()))
|
||||||
|
) << "^^geo:wktLiteral .\n\n";
|
||||||
|
|
||||||
|
Eigen::Map<const Eigen::Matrix<double, 3, Eigen::Dynamic>> vertex_map(o->geometry().verts().data(), 3, o->geometry().verts().size() / 3);
|
||||||
|
|
||||||
|
boost::optional<std::vector<std::vector<int>>::const_iterator> lowest_face;
|
||||||
|
double lowest_z = std::numeric_limits<double>::infinity();
|
||||||
|
|
||||||
|
for (const auto& f : o->geometry().polyhedral_faces_with_holes()) {
|
||||||
|
auto v0 = vertex_map.transpose().row(f[0][0]);
|
||||||
|
auto v1 = vertex_map.transpose().row(f[0][1]);
|
||||||
|
auto v2 = vertex_map.transpose().row(f[0][2]);
|
||||||
|
auto v1_v0 = v1 - v0;
|
||||||
|
auto v2_v0 = v2 - v0;
|
||||||
|
|
||||||
|
Eigen::Vector3d cross_product = v1_v0.cross(v2_v0);
|
||||||
|
cross_product.normalize();
|
||||||
|
// @nb we take abs because so that we can ignore face orientation and potential convatities rquire
|
||||||
|
if ((std::abs(cross_product.z()) + 1.e-9) >= 1.0 && v0.z() < lowest_z) {
|
||||||
|
lowest_face = f.begin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lowest_face) {
|
||||||
|
filename_.stream << "ex:" << ttl_object_id() << " geo:hasGeometry ex:" << ttl_object_id() << "_footprint_geometry .\n\n";
|
||||||
|
filename_.stream << "ex:" << ttl_object_id() << "_footprint_geometry a geo:Geometry ;\n";
|
||||||
|
filename_.stream << " geo:asWKT " << escape_for_turtle(
|
||||||
|
IfcUtil::convert_utf8_to_utf32(
|
||||||
|
capture_output(
|
||||||
|
// @nb this is line_component, because this is the linestring
|
||||||
|
// from a faceboundary, not the edges as pairs of indices.
|
||||||
|
emit_line_component,
|
||||||
|
o->geometry().verts(),
|
||||||
|
**lowest_face,
|
||||||
|
true,
|
||||||
|
POLYGON))
|
||||||
|
) << "^^geo:wktLiteral .\n\n";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
filename_.stream << "ex:" << ttl_object_id() << "_geometry a geo:Geometry ;\n";
|
||||||
|
bool force_2d = true;
|
||||||
|
double z_value;
|
||||||
|
for (size_t i = 2; i < o->geometry().verts().size(); i += 3) {
|
||||||
|
const auto& cur = o->geometry().verts()[i];
|
||||||
|
if (i == 2) {
|
||||||
|
z_value = cur;
|
||||||
|
} else {
|
||||||
|
if (z_value != cur) {
|
||||||
|
force_2d = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filename_.stream << " geo:asWKT " << escape_for_turtle(
|
||||||
|
IfcUtil::convert_utf8_to_utf32(
|
||||||
|
capture_output(
|
||||||
|
emit_line_strings,
|
||||||
|
o->geometry().verts(),
|
||||||
|
o->geometry().edges(),
|
||||||
|
force_2d))
|
||||||
|
) << "^^geo:wktLiteral .\n\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/********************************************************************************
|
||||||
|
* *
|
||||||
|
* 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/>. *
|
||||||
|
* *
|
||||||
|
********************************************************************************/
|
||||||
|
|
||||||
|
#ifndef TTLWKTSERIALIZER_H
|
||||||
|
#define TTLWKTSERIALIZER_H
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
#include <string>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
#include "../serializers/serializers_api.h"
|
||||||
|
#include "../ifcgeom/GeometrySerializer.h"
|
||||||
|
|
||||||
|
// http://people.sc.fsu.edu/~jburkardt/txt/obj_format.txt
|
||||||
|
class SERIALIZERS_API TtlWktSerializer : public WriteOnlyGeometrySerializer {
|
||||||
|
private:
|
||||||
|
stream_or_filename filename_;
|
||||||
|
public:
|
||||||
|
TtlWktSerializer(const stream_or_filename& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings);
|
||||||
|
virtual ~TtlWktSerializer() {}
|
||||||
|
bool ready();
|
||||||
|
void writeHeader();
|
||||||
|
void write(const IfcGeom::TriangulationElement* o);
|
||||||
|
void write(const IfcGeom::BRepElement* /*o*/) {}
|
||||||
|
void finalize() {}
|
||||||
|
bool isTesselated() const { return true; }
|
||||||
|
void setUnitNameAndMagnitude(const std::string& /*name*/, float /*magnitude*/) {}
|
||||||
|
void setFile(IfcParse::IfcFile*) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user