mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-19 03:33:48 +00:00
More work on isolating into plug-ins
This commit is contained in:
@@ -1,34 +1,87 @@
|
||||
add_subdirectory(schema_dependent)
|
||||
set(document_serializer_plugin_runtime_dir "${CMAKE_BINARY_DIR}/serializers/$<CONFIG>")
|
||||
set(geometry_serializer_plugin_runtime_dir "${CMAKE_BINARY_DIR}/serializers/$<CONFIG>")
|
||||
|
||||
file(GLOB SERIALIZERS_H_FILES *.h)
|
||||
file(GLOB SERIALIZERS_CPP_FILES *.cpp)
|
||||
file(GLOB SERIALIZERS_S_H_FILES schema_dependent/*.h)
|
||||
set(SERIALIZERS_FILES ${SERIALIZERS_H_FILES} ${SERIALIZERS_CPP_FILES})
|
||||
|
||||
add_library(Serializers ${SERIALIZERS_FILES})
|
||||
add_library(serialization ALIAS Serializers)
|
||||
set_target_properties(Serializers PROPERTIES COMPILE_FLAGS "-DSERIALIZERS_EXPORTS" VERSION "${PROJECT_VERSION}" SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}")
|
||||
function(add_document_serializer_plugin target output_name)
|
||||
cmake_parse_arguments(PLUGIN "" "" "SOURCES;LIBRARIES" ${ARGN})
|
||||
|
||||
if(WITH_PROJ)
|
||||
find_package(proj REQUIRED)
|
||||
target_compile_definitions(Serializers PRIVATE "WITH_PROJ")
|
||||
if(PROJ_STATIC)
|
||||
target_compile_definitions(Serializers PRIVATE "PROJ_DLL=")
|
||||
add_library(${target} SHARED ${PLUGIN_SOURCES})
|
||||
target_compile_definitions(${target} PRIVATE SERIALIZERS_EXPORTS BOOST_DLL_USE_STD_FS)
|
||||
target_link_libraries(${target} PRIVATE plugin IfcGeom IfcParse ${PLUGIN_LIBRARIES})
|
||||
set_target_properties(${target} PROPERTIES
|
||||
OUTPUT_NAME "${output_name}"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${document_serializer_plugin_runtime_dir}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${document_serializer_plugin_runtime_dir}"
|
||||
)
|
||||
|
||||
list(APPEND document_serializer_libraries ${target})
|
||||
set(document_serializer_libraries ${document_serializer_libraries} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(add_geometry_serializer_plugin target output_name)
|
||||
cmake_parse_arguments(PLUGIN "" "" "SOURCES;LIBRARIES" ${ARGN})
|
||||
|
||||
add_library(${target} SHARED ${PLUGIN_SOURCES})
|
||||
target_compile_definitions(${target} PRIVATE SERIALIZERS_EXPORTS BOOST_DLL_USE_STD_FS)
|
||||
target_link_libraries(${target} PRIVATE plugin IfcGeom IfcParse ${PLUGIN_LIBRARIES})
|
||||
if(WITH_PROJ)
|
||||
find_package(proj REQUIRED)
|
||||
target_compile_definitions(${target} PRIVATE "WITH_PROJ")
|
||||
if(PROJ_STATIC)
|
||||
target_compile_definitions(${target} PRIVATE "PROJ_DLL=")
|
||||
endif()
|
||||
target_link_libraries(${target} PRIVATE proj::proj)
|
||||
endif()
|
||||
target_link_libraries(Serializers PRIVATE proj::proj)
|
||||
set_target_properties(${target} PROPERTIES
|
||||
OUTPUT_NAME "${output_name}"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${geometry_serializer_plugin_runtime_dir}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${geometry_serializer_plugin_runtime_dir}"
|
||||
)
|
||||
|
||||
list(APPEND geometry_serializer_libraries ${target})
|
||||
set(geometry_serializer_libraries ${geometry_serializer_libraries} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
if(WITH_ROCKSDB)
|
||||
add_document_serializer_plugin(document_serializer_rdb "document.rdb" SOURCES document_rdb_plugin.cpp RocksDbSerializer.cpp LIBRARIES RocksDB::rocksdb)
|
||||
endif()
|
||||
|
||||
target_link_libraries(Serializers
|
||||
PRIVATE
|
||||
plugin ${OPENCOLLADA_LIBRARIES} ${USD_LIBRARIES}
|
||||
IfcGeom ${OpenCASCADE_LIBRARIES} IfcParse
|
||||
)
|
||||
add_subdirectory(schema_dependent)
|
||||
|
||||
set(ttl_geometry_serializer_libraries)
|
||||
if(WITH_OPENCASCADE)
|
||||
set(ttl_geometry_serializer_libraries geometry_kernel_opencascade ${OpenCASCADE_LIBRARIES})
|
||||
endif()
|
||||
|
||||
add_geometry_serializer_plugin(geometry_serializer_obj "geometry.obj" SOURCES geometry_obj_plugin.cpp WavefrontObjSerializer.cpp)
|
||||
add_geometry_serializer_plugin(geometry_serializer_ttl "geometry.ttl" SOURCES geometry_ttl_plugin.cpp TtlWktSerializer.cpp LIBRARIES ${ttl_geometry_serializer_libraries})
|
||||
|
||||
if(OPENCOLLADA_FOUND)
|
||||
add_geometry_serializer_plugin(geometry_serializer_dae "geometry.dae" SOURCES geometry_dae_plugin.cpp ColladaSerializer.cpp LIBRARIES ${OPENCOLLADA_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(GLTF_SUPPORT)
|
||||
add_geometry_serializer_plugin(geometry_serializer_glb "geometry.glb" SOURCES geometry_glb_plugin.cpp GltfSerializer.cpp)
|
||||
endif()
|
||||
|
||||
if(USD_SUPPORT)
|
||||
add_geometry_serializer_plugin(geometry_serializer_usd "geometry.usd" SOURCES geometry_usd_plugin.cpp USDSerializer.cpp LIBRARIES ${USD_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(WITH_OPENCASCADE)
|
||||
target_link_libraries(Serializers PRIVATE geometry_kernel_opencascade)
|
||||
set(opencascade_geometry_serializer_libraries geometry_kernel_opencascade ${OpenCASCADE_LIBRARIES})
|
||||
add_geometry_serializer_plugin(geometry_serializer_stp "geometry.stp" SOURCES geometry_stp_plugin.cpp OpenCascadeBasedSerializer.cpp LIBRARIES ${opencascade_geometry_serializer_libraries})
|
||||
add_geometry_serializer_plugin(geometry_serializer_igs "geometry.igs" SOURCES geometry_igs_plugin.cpp OpenCascadeBasedSerializer.cpp LIBRARIES ${opencascade_geometry_serializer_libraries})
|
||||
add_geometry_serializer_plugin(geometry_serializer_svg "geometry.svg" SOURCES geometry_svg_plugin.cpp SvgSerializer.cpp util.cpp LIBRARIES ${opencascade_geometry_serializer_libraries})
|
||||
|
||||
if(HDF5_SUPPORT)
|
||||
add_geometry_serializer_plugin(geometry_serializer_hdf "geometry.hdf" SOURCES geometry_hdf_plugin.cpp HdfSerializer.cpp LIBRARIES ${opencascade_geometry_serializer_libraries} ${HDF5_LIBRARIES})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
install(TARGETS Serializers ${document_serializer_libraries})
|
||||
install(TARGETS ${document_serializer_libraries} ${geometry_serializer_libraries})
|
||||
|
||||
install(FILES ${SERIALIZERS_H_FILES}
|
||||
DESTINATION ${INCLUDEDIR}/serializers/
|
||||
@@ -38,6 +91,5 @@ install(FILES ${SERIALIZERS_S_H_FILES}
|
||||
DESTINATION ${INCLUDEDIR}/serializers/schema_dependent
|
||||
)
|
||||
|
||||
set(IFCOPENSHELL_LIBRARIES ${IFCOPENSHELL_LIBRARIES} Serializers)
|
||||
set(IFCOPENSHELL_LIBRARIES ${IFCOPENSHELL_LIBRARIES} PARENT_SCOPE)
|
||||
set(document_serializer_libraries ${document_serializer_libraries} PARENT_SCOPE)
|
||||
set(geometry_serializer_libraries ${geometry_serializer_libraries} PARENT_SCOPE)
|
||||
|
||||
@@ -1,56 +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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifdef WITH_GLTF
|
||||
|
||||
#include "JsonSerializer.h"
|
||||
#include "document_serializer_plugin.h"
|
||||
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
|
||||
JsonSerializerFactory::Factory::Factory() {
|
||||
ifcopenshell::serializers::load_document_serializer_plugins(*this, "json");
|
||||
}
|
||||
|
||||
void JsonSerializerFactory::Factory::bind(const std::string& schema_name, fn f, const ifcopenshell::plugin::module& module) {
|
||||
const std::string schema_name_lower = boost::to_lower_copy(schema_name);
|
||||
entries_[schema_name_lower] = { f, module };
|
||||
}
|
||||
|
||||
JsonSerializer* JsonSerializerFactory::Factory::construct(const std::string& schema_name, ifcopenshell::file* file, std::string json_filename, JsonSerializer::Dialect dialect) {
|
||||
const std::string schema_name_lower = boost::to_lower_copy(schema_name);
|
||||
auto it = entries_.find(schema_name_lower);
|
||||
if (it == entries_.end()) {
|
||||
throw ifcopenshell::exception("No Json serializer registered for " + schema_name);
|
||||
}
|
||||
return it->second.fn_(file, json_filename, dialect);
|
||||
}
|
||||
|
||||
JsonSerializer::JsonSerializer(ifcopenshell::file* file, const std::string& json_filename, JsonSerializer::Dialect dialect) {
|
||||
if (file) {
|
||||
implementation_ = JsonSerializerFactory::implementations().construct(file->schema()->name(), file, json_filename, dialect);
|
||||
}
|
||||
}
|
||||
|
||||
JsonSerializerFactory::Factory& JsonSerializerFactory::implementations() {
|
||||
static JsonSerializerFactory::Factory impl;
|
||||
return impl;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -7,55 +7,53 @@
|
||||
#include "../ifcparse/file.h"
|
||||
#include "../plugin/plugin.h"
|
||||
#include "../serializers/serializers_api.h"
|
||||
#include "../serializers/document_serializer_plugin.h"
|
||||
|
||||
#include <boost/function.hpp>
|
||||
#include <map>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
class SERIALIZERS_API JsonSerializer : public Serializer {
|
||||
class JsonSerializer : public Serializer {
|
||||
public:
|
||||
enum Dialect {
|
||||
JSON_DIALECT_CREOOX
|
||||
};
|
||||
private:
|
||||
JsonSerializer* implementation_ = nullptr;
|
||||
boost::shared_ptr<Serializer> implementation_;
|
||||
|
||||
protected:
|
||||
std::string json_filename;
|
||||
Dialect dialect_;
|
||||
|
||||
public:
|
||||
JsonSerializer(ifcopenshell::file* file, const std::string& json_filename, Dialect dialect = Dialect::JSON_DIALECT_CREOOX);
|
||||
JsonSerializer(ifcopenshell::file* file, const std::string& json_filename, Dialect dialect = Dialect::JSON_DIALECT_CREOOX)
|
||||
: json_filename(json_filename)
|
||||
, dialect_(dialect)
|
||||
{
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
|
||||
ifcopenshell::serializers::document_serializer_context context;
|
||||
context.file = file;
|
||||
context.output_filename = json_filename;
|
||||
context.schema_name = file->schema()->name();
|
||||
context.dialect = static_cast<int>(dialect);
|
||||
implementation_ = ifcopenshell::serializers::document_serializer_registry_instance().create("json", context);
|
||||
}
|
||||
|
||||
virtual ~JsonSerializer() {}
|
||||
|
||||
bool ready() { return true; }
|
||||
void writeHeader() {}
|
||||
|
||||
void finalize() { implementation_->finalize(); }
|
||||
void finalize() {
|
||||
if (!implementation_) {
|
||||
throw ifcopenshell::exception("No JSON serializer implementation constructed");
|
||||
}
|
||||
implementation_->finalize();
|
||||
}
|
||||
void setFile(ifcopenshell::file*) { throw ifcopenshell::exception("Should be supplied on construction"); }
|
||||
};
|
||||
|
||||
struct SERIALIZERS_API JsonSerializerFactory {
|
||||
typedef boost::function3<JsonSerializer*, ifcopenshell::file*, std::string, JsonSerializer::Dialect> fn;
|
||||
|
||||
class SERIALIZERS_API Factory {
|
||||
public:
|
||||
Factory();
|
||||
void bind(const std::string& schema_name, fn, const ifcopenshell::plugin::module& module = ifcopenshell::plugin::module());
|
||||
JsonSerializer* construct(const std::string& schema_name, ifcopenshell::file*, std::string, JsonSerializer::Dialect);
|
||||
|
||||
private:
|
||||
struct entry {
|
||||
fn fn_;
|
||||
ifcopenshell::plugin::module module_;
|
||||
};
|
||||
|
||||
std::map<std::string, entry> entries_;
|
||||
};
|
||||
|
||||
static Factory& implementations();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -86,17 +86,132 @@
|
||||
|
||||
#include "../ifcgeom/kernels/opencascade/OpenCascadeConversionResult.h"
|
||||
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/tokenizer.hpp>
|
||||
|
||||
#include "SvgSerializer.h"
|
||||
|
||||
namespace {
|
||||
|
||||
const double PI2 = M_PI * 2.;
|
||||
|
||||
std::pair<double, double> parse_svg_bounds(const std::string& value) {
|
||||
unsigned int width = 0;
|
||||
unsigned int height = 0;
|
||||
if (std::sscanf(value.c_str(), "%ux%u", &width, &height) == 2 && width > 0 && height > 0) {
|
||||
return { static_cast<double>(width), static_cast<double>(height) };
|
||||
}
|
||||
throw std::runtime_error("Invalid use of --bounds");
|
||||
}
|
||||
|
||||
std::pair<double, double> parse_svg_center(const std::string& value) {
|
||||
double center_x = 0.;
|
||||
double center_y = 0.;
|
||||
if (std::sscanf(value.c_str(), "%lfx%lf", ¢er_x, ¢er_y) == 2 &&
|
||||
center_x >= 0. && center_y >= 0. &&
|
||||
center_x <= 1. && center_y <= 1.) {
|
||||
return { center_x, center_y };
|
||||
}
|
||||
throw std::runtime_error("Invalid use of --center");
|
||||
}
|
||||
|
||||
double parse_svg_scale(const std::string& value) {
|
||||
unsigned int numerator = 0;
|
||||
unsigned int denominator = 0;
|
||||
if (std::sscanf(value.c_str(), "%u:%u", &numerator, &denominator) == 2 &&
|
||||
numerator > 0 && denominator > 0) {
|
||||
return static_cast<double>(numerator) / denominator;
|
||||
}
|
||||
throw std::runtime_error("Invalid use of --scale");
|
||||
}
|
||||
|
||||
SvgSerializer::storey_height_display_types parse_storey_height_display(const std::string& value) {
|
||||
const auto display = boost::to_lower_copy(value);
|
||||
if (display == "none") {
|
||||
return SvgSerializer::SH_NONE;
|
||||
}
|
||||
if (display == "full") {
|
||||
return SvgSerializer::SH_FULL;
|
||||
}
|
||||
if (display == "left") {
|
||||
return SvgSerializer::SH_LEFT;
|
||||
}
|
||||
throw std::runtime_error("Invalid use of --draw-storey-heights, expected none|full|left");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool SvgSerializer::ready() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void SvgSerializer::apply_settings() {
|
||||
using namespace ifcopenshell::geometry::settings;
|
||||
|
||||
if (settings().get<SvgBounds>().has()) {
|
||||
const auto bounds = parse_svg_bounds(settings().get<SvgBounds>().get());
|
||||
setBoundingRectangle(bounds.first, bounds.second);
|
||||
}
|
||||
|
||||
if (settings().get<SvgScale>().has()) {
|
||||
setScale(parse_svg_scale(settings().get<SvgScale>().get()));
|
||||
}
|
||||
|
||||
if (settings().get<SvgCenter>().has()) {
|
||||
const auto center = parse_svg_center(settings().get<SvgCenter>().get());
|
||||
setDrawingCenter(center.first, center.second);
|
||||
}
|
||||
|
||||
if (settings().get<SvgSectionHeightFromStoreys>().get()) {
|
||||
if (settings().get<SvgSectionHeight>().has()) {
|
||||
setSectionHeightsFromStoreys(settings().get<SvgSectionHeight>().get());
|
||||
} else {
|
||||
setSectionHeightsFromStoreys();
|
||||
}
|
||||
} else if (settings().get<SvgSectionHeight>().has()) {
|
||||
setSectionHeight(settings().get<SvgSectionHeight>().get());
|
||||
}
|
||||
|
||||
setPrintSpaceNames(settings().get<SvgPrintSpaceNames>().get());
|
||||
setPrintSpaceAreas(settings().get<SvgPrintSpaceAreas>().get());
|
||||
setDrawDoorArcs(settings().get<SvgDoorArcs>().get());
|
||||
setAutoSection(settings().get<SvgAutoSection>().get());
|
||||
setAutoElevation(settings().get<SvgAutoElevation>().get());
|
||||
setUseNamespace(settings().get<SvgUseNamespace>().get());
|
||||
setUseHlrPoly(settings().get<SvgUseHlrPoly>().get());
|
||||
setUsePrefiltering(settings().get<SvgUsePrefiltering>().get());
|
||||
setSegmentProjection(settings().get<SvgSegmentProjection>().get());
|
||||
setPolygonal(settings().get<SvgPolygonal>().get());
|
||||
setAlwaysProject(settings().get<SvgAlwaysProject>().get());
|
||||
setWithoutStoreys(settings().get<SvgWithoutStoreys>().get());
|
||||
setNoCSS(settings().get<SvgNoCss>().get());
|
||||
|
||||
if (settings().get<SvgDrawStoreyHeights>().has()) {
|
||||
setDrawStoreyHeights(parse_storey_height_display(settings().get<SvgDrawStoreyHeights>().get()));
|
||||
}
|
||||
|
||||
if (settings().get<SvgStoreyHeightLineLength>().has()) {
|
||||
setStoreyHeightLineLength(settings().get<SvgStoreyHeightLineLength>().get());
|
||||
}
|
||||
|
||||
if (settings().get<SvgSpaceNameTransform>().has()) {
|
||||
setSpaceNameTransform(settings().get<SvgSpaceNameTransform>().get());
|
||||
}
|
||||
|
||||
if (settings().get<SvgSectionRef>().has()) {
|
||||
setSectionRef(settings().get<SvgSectionRef>().get());
|
||||
}
|
||||
|
||||
if (settings().get<SvgElevationRef>().has()) {
|
||||
setElevationRef(settings().get<SvgElevationRef>().get());
|
||||
}
|
||||
|
||||
if (settings().get<SvgElevationRefGuid>().has()) {
|
||||
setElevationRefGuid(settings().get<SvgElevationRefGuid>().get());
|
||||
}
|
||||
}
|
||||
|
||||
void SvgSerializer::write(path_object& p, const TopoDS_Shape& comp_or_wire, std::optional<std::vector<double>> dash_array) {
|
||||
/* ShapeFix_Wire fix;
|
||||
Handle(ShapeExtend_WireData) data = new ShapeExtend_WireData;
|
||||
|
||||
@@ -589,6 +589,7 @@ protected:
|
||||
Bnd_Box bnd_;
|
||||
|
||||
void draw_hlr(const gp_Pln& pln, const drawing_key& drawing_name);
|
||||
void apply_settings();
|
||||
|
||||
subtract_before_project subtraction_settings_;
|
||||
|
||||
@@ -627,7 +628,9 @@ public:
|
||||
, hlr(nullptr)
|
||||
, namespace_prefix_("data-")
|
||||
, subtraction_settings_(ON_SLABS_AT_FLOORPLANS)
|
||||
{}
|
||||
{
|
||||
apply_settings();
|
||||
}
|
||||
void addXCoordinate(const boost::shared_ptr<util::string_buffer::float_item>& fi) { xcoords.push_back(fi); }
|
||||
void addYCoordinate(const boost::shared_ptr<util::string_buffer::float_item>& fi) { ycoords.push_back(fi); }
|
||||
void addSizeComponent(const boost::shared_ptr<util::string_buffer::float_item>& fi) { radii.push_back(fi); }
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
#include "XmlSerializer.h"
|
||||
#include "document_serializer_plugin.h"
|
||||
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
|
||||
XmlSerializerFactory::Factory::Factory() {
|
||||
ifcopenshell::serializers::load_document_serializer_plugins(*this, "xml");
|
||||
}
|
||||
|
||||
void XmlSerializerFactory::Factory::bind(const std::string& schema_name, fn f, const ifcopenshell::plugin::module& module) {
|
||||
const std::string schema_name_lower = boost::to_lower_copy(schema_name);
|
||||
entries_[schema_name_lower] = { f, module };
|
||||
}
|
||||
|
||||
XmlSerializer* XmlSerializerFactory::Factory::construct(const std::string& schema_name, ifcopenshell::file* file, std::string xml_filename) {
|
||||
const std::string schema_name_lower = boost::to_lower_copy(schema_name);
|
||||
auto it = entries_.find(schema_name_lower);
|
||||
if (it == entries_.end()) {
|
||||
throw ifcopenshell::exception("No XML serializer registered for " + schema_name);
|
||||
}
|
||||
return it->second.fn_(file, xml_filename);
|
||||
}
|
||||
|
||||
XmlSerializer::XmlSerializer(ifcopenshell::file* file, const std::string& xml_filename) {
|
||||
if (file) {
|
||||
implementation_ = XmlSerializerFactory::implementations().construct(file->schema()->name(), file, xml_filename);
|
||||
}
|
||||
}
|
||||
|
||||
XmlSerializerFactory::Factory& XmlSerializerFactory::implementations() {
|
||||
static XmlSerializerFactory::Factory impl;
|
||||
return impl;
|
||||
}
|
||||
@@ -7,49 +7,44 @@
|
||||
#include "../ifcgeom/Serializer.h"
|
||||
#include "../ifcparse/file.h"
|
||||
#include "../plugin/plugin.h"
|
||||
#include "../serializers/document_serializer_plugin.h"
|
||||
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <map>
|
||||
|
||||
class SERIALIZERS_API XmlSerializer : public Serializer {
|
||||
class XmlSerializer : public Serializer {
|
||||
private:
|
||||
XmlSerializer* implementation_ = nullptr;
|
||||
boost::shared_ptr<Serializer> implementation_;
|
||||
|
||||
protected:
|
||||
std::string xml_filename;
|
||||
|
||||
public:
|
||||
XmlSerializer(ifcopenshell::file* file, const std::string& xml_filename);
|
||||
XmlSerializer(ifcopenshell::file* file, const std::string& xml_filename)
|
||||
: xml_filename(xml_filename)
|
||||
{
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
|
||||
ifcopenshell::serializers::document_serializer_context context;
|
||||
context.file = file;
|
||||
context.output_filename = xml_filename;
|
||||
context.schema_name = file->schema()->name();
|
||||
implementation_ = ifcopenshell::serializers::document_serializer_registry_instance().create("xml", context);
|
||||
}
|
||||
|
||||
virtual ~XmlSerializer() {}
|
||||
|
||||
bool ready() { return true; }
|
||||
void writeHeader() {}
|
||||
|
||||
void finalize() { implementation_->finalize(); }
|
||||
void finalize() {
|
||||
if (!implementation_) {
|
||||
throw ifcopenshell::exception("No XML serializer implementation constructed");
|
||||
}
|
||||
implementation_->finalize();
|
||||
}
|
||||
void setFile(ifcopenshell::file*) { throw ifcopenshell::exception("Should be supplied on construction"); }
|
||||
};
|
||||
|
||||
struct SERIALIZERS_API XmlSerializerFactory {
|
||||
typedef boost::function2<XmlSerializer*, ifcopenshell::file*, std::string> fn;
|
||||
|
||||
class SERIALIZERS_API Factory {
|
||||
public:
|
||||
Factory();
|
||||
void bind(const std::string& schema_name, fn, const ifcopenshell::plugin::module& module = ifcopenshell::plugin::module());
|
||||
XmlSerializer* construct(const std::string& schema_name, ifcopenshell::file*, std::string);
|
||||
|
||||
private:
|
||||
struct entry {
|
||||
fn fn_;
|
||||
ifcopenshell::plugin::module module_;
|
||||
};
|
||||
|
||||
std::map<std::string, entry> entries_;
|
||||
};
|
||||
|
||||
static Factory& implementations();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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 "document_serializer_plugin.h"
|
||||
#include "RocksDbSerializer.h"
|
||||
|
||||
#ifdef IFOPSH_WITH_ROCKSDB
|
||||
|
||||
#include <boost/dll/alias.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
boost::shared_ptr<Serializer> create_serializer(const ifcopenshell::serializers::document_serializer_context& context) {
|
||||
if (!context.stream || context.input_filename.empty()) {
|
||||
throw ifcopenshell::exception("RocksDB document serializer requires --stream input");
|
||||
}
|
||||
return boost::make_shared<RocksDbSerializer>(context.input_filename, context.output_filename, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace serializers {
|
||||
namespace rdb_document_serializer_plugin {
|
||||
|
||||
plugin::abi_info plugin_abi() {
|
||||
return plugin::host_abi();
|
||||
}
|
||||
|
||||
plugin::metadata plugin_metadata() {
|
||||
return document_serializer_plugin_metadata("rdb");
|
||||
}
|
||||
|
||||
void register_plugin(document_serializer_registry& registry, const plugin::module& module) {
|
||||
document_serializer_info info;
|
||||
info.format = "rdb";
|
||||
info.supports_ifc_file = false;
|
||||
info.supports_input_filename = true;
|
||||
info.writes_final_output = true;
|
||||
registry.bind(info, create_serializer, module);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::rdb_document_serializer_plugin::plugin_abi, ifcopenshell_plugin_abi_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::rdb_document_serializer_plugin::plugin_metadata, ifcopenshell_plugin_metadata_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::rdb_document_serializer_plugin::register_plugin, ifcopenshell_register_document_serializer_plugin_v1)
|
||||
|
||||
#endif
|
||||
@@ -21,35 +21,117 @@
|
||||
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
|
||||
#include "../ifcparse/logger.h"
|
||||
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
|
||||
namespace {
|
||||
|
||||
std::string document_serializer_plugin_prefix(const std::string& format) {
|
||||
return "document." + boost::to_lower_copy(format) + ".";
|
||||
std::string document_serializer_key(const std::string& format) {
|
||||
if (format.empty()) {
|
||||
return format;
|
||||
}
|
||||
|
||||
auto key = boost::to_lower_copy(format);
|
||||
if (key.front() == '.') {
|
||||
key.erase(key.begin());
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
template <typename registry_t, typename register_plugin_t>
|
||||
void load_document_serializer_plugins_impl(registry_t& registry, const std::string& format) {
|
||||
ifcopenshell::plugin::manager manager;
|
||||
manager.add_search_path(ifcopenshell::serializers::document_serializer_plugin_directory());
|
||||
std::string document_serializer_schema_key(const std::string& schema_name) {
|
||||
return boost::to_upper_copy(schema_name);
|
||||
}
|
||||
|
||||
const auto format_lower = boost::to_lower_copy(format);
|
||||
const auto prefix = document_serializer_plugin_prefix(format_lower);
|
||||
for (const auto& path : manager.discover(prefix)) {
|
||||
auto module = manager.load(path);
|
||||
if (module.meta().kind_ != ifcopenshell::plugin::kind::document_serializer) {
|
||||
continue;
|
||||
}
|
||||
if (boost::to_lower_copy(module.meta().format) != format_lower) {
|
||||
continue;
|
||||
}
|
||||
std::string document_serializer_plugin_prefix(const std::string& format = std::string()) {
|
||||
const auto format_key = document_serializer_key(format);
|
||||
return format_key.empty() ? "document." : "document." + format_key;
|
||||
}
|
||||
|
||||
auto register_plugin = module.get_alias<register_plugin_t>(ifcopenshell::serializers::document_serializer_plugin_registration_symbol());
|
||||
register_plugin(registry, module);
|
||||
void add_document_serializer_search_paths(ifcopenshell::plugin::manager& manager) {
|
||||
const auto directory = ifcopenshell::serializers::document_serializer_plugin_directory();
|
||||
manager.add_search_path(directory);
|
||||
|
||||
const auto sibling_directory = directory.parent_path().parent_path() / "serializers" / directory.filename();
|
||||
if (sibling_directory != directory && std::filesystem::exists(sibling_directory)) {
|
||||
manager.add_search_path(sibling_directory);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ifcopenshell::serializers::document_serializer_registry::bind(const document_serializer_info& info, create_fn create, const plugin::module& module) {
|
||||
entry entry;
|
||||
entry.info_ = info;
|
||||
entry.info_.format = document_serializer_key(entry.info_.format);
|
||||
entry.info_.schema_name = document_serializer_schema_key(entry.info_.schema_name);
|
||||
entry.create_ = create;
|
||||
entry.module_ = module.meta().id.empty() ? plugin::module(document_serializer_plugin_metadata(entry.info_.format, entry.info_.schema_name)) : module;
|
||||
|
||||
entries_[entry.info_.format].push_back(entry);
|
||||
}
|
||||
|
||||
const ifcopenshell::serializers::document_serializer_registry::entry* ifcopenshell::serializers::document_serializer_registry::find_entry_(const std::string& format, const std::string& schema_name) const {
|
||||
const auto format_key = document_serializer_key(format);
|
||||
const auto iter = entries_.find(format_key);
|
||||
if (iter == entries_.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto schema_key = document_serializer_schema_key(schema_name);
|
||||
const entry* fallback = nullptr;
|
||||
|
||||
for (const auto& candidate : iter->second) {
|
||||
if (candidate.info_.schema_name.empty()) {
|
||||
if (!fallback) {
|
||||
fallback = &candidate;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!schema_key.empty() && candidate.info_.schema_name == schema_key) {
|
||||
return &candidate;
|
||||
}
|
||||
if (schema_key.empty() && !fallback) {
|
||||
fallback = &candidate;
|
||||
}
|
||||
}
|
||||
|
||||
return fallback;
|
||||
}
|
||||
|
||||
const ifcopenshell::serializers::document_serializer_info* ifcopenshell::serializers::document_serializer_registry::find(const std::string& format, const std::string& schema_name) const {
|
||||
const auto* entry = find_entry_(format, schema_name);
|
||||
return entry ? &entry->info_ : nullptr;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Serializer> ifcopenshell::serializers::document_serializer_registry::create(const std::string& format, const document_serializer_context& context) const {
|
||||
const auto schema_name = !context.schema_name.empty() ? context.schema_name :
|
||||
(context.file ? context.file->schema()->name() : std::string());
|
||||
const auto* entry = find_entry_(format, schema_name);
|
||||
if (!entry) {
|
||||
throw ifcopenshell::exception("No document serializer registered for " + format + (schema_name.empty() ? std::string() : " and schema " + schema_name));
|
||||
}
|
||||
return entry->create_(context);
|
||||
}
|
||||
|
||||
std::vector<ifcopenshell::serializers::document_serializer_info> ifcopenshell::serializers::document_serializer_registry::serializers() const {
|
||||
std::vector<document_serializer_info> result;
|
||||
std::set<std::string> seen;
|
||||
|
||||
for (const auto& pair : entries_) {
|
||||
for (const auto& entry : pair.second) {
|
||||
const auto key = entry.info_.format + "|" + entry.info_.schema_name;
|
||||
if (!seen.insert(key).second) {
|
||||
continue;
|
||||
}
|
||||
result.push_back(entry.info_);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* ifcopenshell::serializers::document_serializer_plugin_registration_symbol() {
|
||||
return "ifcopenshell_register_document_serializer_plugin_v1";
|
||||
}
|
||||
@@ -57,9 +139,12 @@ const char* ifcopenshell::serializers::document_serializer_plugin_registration_s
|
||||
ifcopenshell::plugin::metadata ifcopenshell::serializers::document_serializer_plugin_metadata(const std::string& format, const std::string& schema_name) {
|
||||
plugin::metadata metadata;
|
||||
metadata.kind_ = plugin::kind::document_serializer;
|
||||
metadata.id = document_serializer_plugin_prefix(format) + boost::to_lower_copy(schema_name);
|
||||
metadata.schema = boost::to_upper_copy(schema_name);
|
||||
metadata.format = boost::to_lower_copy(format);
|
||||
metadata.id = document_serializer_plugin_prefix(format);
|
||||
if (!schema_name.empty()) {
|
||||
metadata.id += "." + boost::to_lower_copy(schema_name);
|
||||
}
|
||||
metadata.schema = document_serializer_schema_key(schema_name);
|
||||
metadata.format = document_serializer_key(format);
|
||||
return metadata;
|
||||
}
|
||||
|
||||
@@ -67,12 +152,30 @@ std::filesystem::path ifcopenshell::serializers::document_serializer_plugin_dire
|
||||
return plugin::module_directory(reinterpret_cast<const void*>(&ifcopenshell::serializers::document_serializer_plugin_directory));
|
||||
}
|
||||
|
||||
void ifcopenshell::serializers::load_document_serializer_plugins(XmlSerializerFactory::Factory& registry, const std::string& format) {
|
||||
load_document_serializer_plugins_impl<XmlSerializerFactory::Factory, register_xml_document_serializer_plugin_fn>(registry, format);
|
||||
void ifcopenshell::serializers::load_document_serializer_plugins(document_serializer_registry& registry) {
|
||||
ifcopenshell::plugin::manager manager;
|
||||
add_document_serializer_search_paths(manager);
|
||||
|
||||
for (const auto& path : manager.discover(document_serializer_plugin_prefix())) {
|
||||
ifcopenshell::plugin::module module;
|
||||
try {
|
||||
module = manager.load(path);
|
||||
} catch (const std::exception& e) {
|
||||
logger::error(e);
|
||||
continue;
|
||||
}
|
||||
if (module.meta().kind_ != ifcopenshell::plugin::kind::document_serializer) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto register_plugin = module.get_alias<register_document_serializer_plugin_fn>(document_serializer_plugin_registration_symbol());
|
||||
register_plugin(registry, module);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_GLTF
|
||||
void ifcopenshell::serializers::load_document_serializer_plugins(JsonSerializerFactory::Factory& registry, const std::string& format) {
|
||||
load_document_serializer_plugins_impl<JsonSerializerFactory::Factory, register_json_document_serializer_plugin_fn>(registry, format);
|
||||
ifcopenshell::serializers::document_serializer_registry& ifcopenshell::serializers::document_serializer_registry_instance() {
|
||||
static document_serializer_registry registry;
|
||||
static std::once_flag once;
|
||||
std::call_once(once, load_document_serializer_plugins, std::ref(registry));
|
||||
return registry;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -20,30 +20,67 @@
|
||||
#ifndef IFCOPENSHELL_DOCUMENT_SERIALIZER_PLUGIN_H
|
||||
#define IFCOPENSHELL_DOCUMENT_SERIALIZER_PLUGIN_H
|
||||
|
||||
#include "XmlSerializer.h"
|
||||
#include "../serializers/serializers_api.h"
|
||||
#include "../ifcgeom/Serializer.h"
|
||||
#include "../ifcparse/file.h"
|
||||
#include "../plugin/plugin.h"
|
||||
|
||||
#ifdef WITH_GLTF
|
||||
#include "JsonSerializer.h"
|
||||
#endif
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <filesystem>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace serializers {
|
||||
|
||||
typedef void register_xml_document_serializer_plugin_fn(XmlSerializerFactory::Factory&, const ifcopenshell::plugin::module&);
|
||||
struct SERIALIZERS_API document_serializer_info {
|
||||
std::string format;
|
||||
std::string schema_name;
|
||||
bool supports_ifc_file = true;
|
||||
bool supports_input_filename = false;
|
||||
bool writes_final_output = false;
|
||||
};
|
||||
|
||||
struct SERIALIZERS_API document_serializer_context {
|
||||
ifcopenshell::file* file = nullptr;
|
||||
std::string input_filename;
|
||||
std::string output_filename;
|
||||
std::string schema_name;
|
||||
bool stream = false;
|
||||
int dialect = 0;
|
||||
};
|
||||
|
||||
class SERIALIZERS_API document_serializer_registry {
|
||||
public:
|
||||
typedef boost::function<boost::shared_ptr<Serializer>(const document_serializer_context&)> create_fn;
|
||||
|
||||
void bind(const document_serializer_info& info, create_fn create, const ifcopenshell::plugin::module& module = ifcopenshell::plugin::module());
|
||||
const document_serializer_info* find(const std::string& format, const std::string& schema_name = std::string()) const;
|
||||
boost::shared_ptr<Serializer> create(const std::string& format, const document_serializer_context& context) const;
|
||||
std::vector<document_serializer_info> serializers() const;
|
||||
|
||||
private:
|
||||
struct entry {
|
||||
document_serializer_info info_;
|
||||
create_fn create_;
|
||||
ifcopenshell::plugin::module module_;
|
||||
};
|
||||
|
||||
const entry* find_entry_(const std::string& format, const std::string& schema_name) const;
|
||||
|
||||
std::map<std::string, std::vector<entry>> entries_;
|
||||
};
|
||||
|
||||
typedef void register_document_serializer_plugin_fn(document_serializer_registry&, const ifcopenshell::plugin::module&);
|
||||
|
||||
SERIALIZERS_API const char* document_serializer_plugin_registration_symbol();
|
||||
SERIALIZERS_API ifcopenshell::plugin::metadata document_serializer_plugin_metadata(const std::string& format, const std::string& schema_name);
|
||||
SERIALIZERS_API ifcopenshell::plugin::metadata document_serializer_plugin_metadata(const std::string& format, const std::string& schema_name = std::string());
|
||||
SERIALIZERS_API std::filesystem::path document_serializer_plugin_directory();
|
||||
SERIALIZERS_API void load_document_serializer_plugins(XmlSerializerFactory::Factory& registry, const std::string& format);
|
||||
|
||||
#ifdef WITH_GLTF
|
||||
typedef void register_json_document_serializer_plugin_fn(JsonSerializerFactory::Factory&, const ifcopenshell::plugin::module&);
|
||||
|
||||
SERIALIZERS_API void load_document_serializer_plugins(JsonSerializerFactory::Factory& registry, const std::string& format);
|
||||
#endif
|
||||
SERIALIZERS_API void load_document_serializer_plugins(document_serializer_registry& registry);
|
||||
SERIALIZERS_API document_serializer_registry& document_serializer_registry_instance();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifdef WITH_OPENCOLLADA
|
||||
|
||||
#include "ColladaSerializer.h"
|
||||
#include "geometry_serializer_plugin.h"
|
||||
|
||||
#include <boost/dll/alias.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace serializers {
|
||||
namespace geometry_dae_plugin {
|
||||
|
||||
plugin::abi_info plugin_abi() {
|
||||
return plugin::host_abi();
|
||||
}
|
||||
|
||||
plugin::metadata plugin_metadata() {
|
||||
return geometry_serializer_plugin_metadata("dae");
|
||||
}
|
||||
|
||||
boost::shared_ptr<GeometrySerializer> create_serializer(const geometry_serializer_context& context) {
|
||||
return boost::make_shared<ColladaSerializer>(context.output_temp_filename, context.geometry_settings, context.serializer_settings);
|
||||
}
|
||||
|
||||
void register_plugin(geometry_serializer_registry& registry, const plugin::module& module) {
|
||||
geometry_serializer_info info;
|
||||
info.format = "dae";
|
||||
info.extensions = { ".dae" };
|
||||
info.supports_triangulation = true;
|
||||
info.supports_user_element_hierarchy = true;
|
||||
info.requires_ascii_temp_file = true;
|
||||
registry.bind(info, create_serializer, geometry_serializer_registry::configure_fn(), module);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_dae_plugin::plugin_abi, ifcopenshell_plugin_abi_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_dae_plugin::plugin_metadata, ifcopenshell_plugin_metadata_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_dae_plugin::register_plugin, ifcopenshell_register_geometry_serializer_plugin_v1)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,61 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifdef WITH_GLTF
|
||||
|
||||
#include "geometry_serializer_plugin.h"
|
||||
#include "GltfSerializer.h"
|
||||
|
||||
#include <boost/dll/alias.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace serializers {
|
||||
namespace geometry_glb_plugin {
|
||||
|
||||
plugin::abi_info plugin_abi() {
|
||||
return plugin::host_abi();
|
||||
}
|
||||
|
||||
plugin::metadata plugin_metadata() {
|
||||
return geometry_serializer_plugin_metadata("glb");
|
||||
}
|
||||
|
||||
boost::shared_ptr<GeometrySerializer> create_serializer(const geometry_serializer_context& context) {
|
||||
return boost::make_shared<GltfSerializer>(context.output_temp_filename, context.geometry_settings, context.serializer_settings);
|
||||
}
|
||||
|
||||
void register_plugin(geometry_serializer_registry& registry, const plugin::module& module) {
|
||||
geometry_serializer_info info;
|
||||
info.format = "glb";
|
||||
info.extensions = { ".glb" };
|
||||
info.supports_triangulation = true;
|
||||
info.supports_user_element_hierarchy = true;
|
||||
registry.bind(info, create_serializer, geometry_serializer_registry::configure_fn(), module);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_glb_plugin::plugin_abi, ifcopenshell_plugin_abi_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_glb_plugin::plugin_metadata, ifcopenshell_plugin_metadata_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_glb_plugin::register_plugin, ifcopenshell_register_geometry_serializer_plugin_v1)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,66 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#if defined(WITH_HDF5) && defined(IFOPSH_WITH_OPENCASCADE)
|
||||
|
||||
#include "geometry_serializer_plugin.h"
|
||||
#include "HdfSerializer.h"
|
||||
|
||||
#include <boost/dll/alias.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace serializers {
|
||||
namespace geometry_hdf_plugin {
|
||||
|
||||
plugin::abi_info plugin_abi() {
|
||||
return plugin::host_abi();
|
||||
}
|
||||
|
||||
plugin::metadata plugin_metadata() {
|
||||
return geometry_serializer_plugin_metadata("hdf");
|
||||
}
|
||||
|
||||
boost::shared_ptr<GeometrySerializer> create_serializer(const geometry_serializer_context& context) {
|
||||
return boost::make_shared<HdfSerializer>(context.output_temp_filename, context.geometry_settings, context.serializer_settings);
|
||||
}
|
||||
|
||||
void configure_serializer(geometry_serializer_context& context) {
|
||||
context.geometry_settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
|
||||
}
|
||||
|
||||
void register_plugin(geometry_serializer_registry& registry, const plugin::module& module) {
|
||||
geometry_serializer_info info;
|
||||
info.format = "hdf";
|
||||
info.extensions = { ".h5" };
|
||||
info.kernel_ids = { "opencascade" };
|
||||
info.supports_triangulation = true;
|
||||
info.supports_brep = true;
|
||||
registry.bind(info, create_serializer, configure_serializer, module);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_hdf_plugin::plugin_abi, ifcopenshell_plugin_abi_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_hdf_plugin::plugin_metadata, ifcopenshell_plugin_metadata_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_hdf_plugin::register_plugin, ifcopenshell_register_geometry_serializer_plugin_v1)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,76 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifdef IFOPSH_WITH_OPENCASCADE
|
||||
|
||||
#include "geometry_serializer_plugin.h"
|
||||
#include "IgesSerializer.h"
|
||||
|
||||
#include <boost/dll/alias.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
#include <Standard_Version.hxx>
|
||||
|
||||
#if OCC_VERSION_HEX < 0x60900
|
||||
#include <IGESControl_Controller.hxx>
|
||||
#endif
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace serializers {
|
||||
namespace geometry_igs_plugin {
|
||||
|
||||
plugin::abi_info plugin_abi() {
|
||||
return plugin::host_abi();
|
||||
}
|
||||
|
||||
plugin::metadata plugin_metadata() {
|
||||
return geometry_serializer_plugin_metadata("igs");
|
||||
}
|
||||
|
||||
boost::shared_ptr<GeometrySerializer> create_serializer(const geometry_serializer_context& context) {
|
||||
#if OCC_VERSION_HEX < 0x60900
|
||||
IGESControl_Controller::Init();
|
||||
#endif
|
||||
return boost::make_shared<IgesSerializer>(context.output_temp_filename, context.geometry_settings, context.serializer_settings);
|
||||
}
|
||||
|
||||
void configure_serializer(geometry_serializer_context& context) {
|
||||
context.geometry_settings.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = true;
|
||||
context.geometry_settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
|
||||
}
|
||||
|
||||
void register_plugin(geometry_serializer_registry& registry, const plugin::module& module) {
|
||||
geometry_serializer_info info;
|
||||
info.format = "igs";
|
||||
info.extensions = { ".igs" };
|
||||
info.kernel_ids = { "opencascade" };
|
||||
info.supports_brep = true;
|
||||
info.requires_ascii_temp_file = true;
|
||||
registry.bind(info, create_serializer, configure_serializer, module);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_igs_plugin::plugin_abi, ifcopenshell_plugin_abi_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_igs_plugin::plugin_metadata, ifcopenshell_plugin_metadata_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_igs_plugin::register_plugin, ifcopenshell_register_geometry_serializer_plugin_v1)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,74 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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 "geometry_serializer_plugin.h"
|
||||
#include "WavefrontObjSerializer.h"
|
||||
|
||||
#include "../ifcparse/utils.h"
|
||||
|
||||
#include <boost/dll/alias.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
namespace {
|
||||
|
||||
std::string obj_mtl_filename(const std::string& output_filename) {
|
||||
std::filesystem::path path(ifcopenshell::path::from_utf8(output_filename));
|
||||
path.replace_extension(ifcopenshell::path::from_utf8(".mtl"));
|
||||
return ifcopenshell::path::to_utf8(path.native());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace serializers {
|
||||
namespace geometry_obj_plugin {
|
||||
|
||||
plugin::abi_info plugin_abi() {
|
||||
return plugin::host_abi();
|
||||
}
|
||||
|
||||
plugin::metadata plugin_metadata() {
|
||||
return geometry_serializer_plugin_metadata("obj");
|
||||
}
|
||||
|
||||
boost::shared_ptr<GeometrySerializer> create_serializer(const geometry_serializer_context& context) {
|
||||
return boost::make_shared<WaveFrontOBJSerializer>(context.output_temp_filename, obj_mtl_filename(context.output_filename), context.geometry_settings, context.serializer_settings);
|
||||
}
|
||||
|
||||
void configure_serializer(geometry_serializer_context& context) {
|
||||
context.geometry_settings.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = true;
|
||||
}
|
||||
|
||||
void register_plugin(geometry_serializer_registry& registry, const plugin::module& module) {
|
||||
geometry_serializer_info info;
|
||||
info.format = "obj";
|
||||
info.extensions = { ".obj" };
|
||||
info.supports_triangulation = true;
|
||||
registry.bind(info, create_serializer, configure_serializer, module);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_obj_plugin::plugin_abi, ifcopenshell_plugin_abi_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_obj_plugin::plugin_metadata, ifcopenshell_plugin_metadata_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_obj_plugin::register_plugin, ifcopenshell_register_geometry_serializer_plugin_v1)
|
||||
@@ -0,0 +1,160 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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 "geometry_serializer_plugin.h"
|
||||
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
|
||||
namespace {
|
||||
|
||||
std::string geometry_serializer_plugin_prefix(const std::string& format = std::string()) {
|
||||
const auto format_lower = boost::to_lower_copy(format);
|
||||
return format_lower.empty() ? "geometry." : "geometry." + format_lower;
|
||||
}
|
||||
|
||||
std::string geometry_serializer_key(const std::string& extension) {
|
||||
if (extension.empty()) {
|
||||
return extension;
|
||||
}
|
||||
|
||||
auto key = boost::to_lower_copy(extension);
|
||||
if (key.front() != '.') {
|
||||
key.insert(key.begin(), '.');
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
void add_geometry_serializer_search_paths(ifcopenshell::plugin::manager& manager) {
|
||||
const auto directory = ifcopenshell::serializers::geometry_serializer_plugin_directory();
|
||||
manager.add_search_path(directory);
|
||||
|
||||
const auto sibling_directory = directory.parent_path().parent_path() / "serializers" / directory.filename();
|
||||
if (sibling_directory != directory && std::filesystem::exists(sibling_directory)) {
|
||||
manager.add_search_path(sibling_directory);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ifcopenshell::serializers::geometry_serializer_registry::bind(const geometry_serializer_info& info, create_fn create, configure_fn configure, const plugin::module& module) {
|
||||
entry entry;
|
||||
entry.info_ = info;
|
||||
entry.info_.format = boost::to_lower_copy(entry.info_.format);
|
||||
entry.create_ = create;
|
||||
entry.configure_ = configure;
|
||||
entry.module_ = module.meta().id.empty() ? plugin::module(geometry_serializer_plugin_metadata(entry.info_.format)) : module;
|
||||
|
||||
if (entry.info_.extensions.empty() && !entry.info_.format.empty()) {
|
||||
entry.info_.extensions.push_back("." + entry.info_.format);
|
||||
}
|
||||
|
||||
for (auto& extension : entry.info_.extensions) {
|
||||
extension = geometry_serializer_key(extension);
|
||||
entries_[extension] = entry;
|
||||
}
|
||||
}
|
||||
|
||||
bool ifcopenshell::serializers::geometry_serializer_registry::has(const std::string& extension) const {
|
||||
return entries_.find(geometry_serializer_key(extension)) != entries_.end();
|
||||
}
|
||||
|
||||
const ifcopenshell::serializers::geometry_serializer_info* ifcopenshell::serializers::geometry_serializer_registry::find(const std::string& extension) const {
|
||||
const auto iter = entries_.find(geometry_serializer_key(extension));
|
||||
if (iter == entries_.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
return &iter->second.info_;
|
||||
}
|
||||
|
||||
void ifcopenshell::serializers::geometry_serializer_registry::configure(const std::string& extension, geometry_serializer_context& context) const {
|
||||
const auto iter = entries_.find(geometry_serializer_key(extension));
|
||||
if (iter == entries_.end()) {
|
||||
throw ifcopenshell::exception("No geometry serializer registered for " + extension);
|
||||
}
|
||||
if (iter->second.configure_) {
|
||||
iter->second.configure_(context);
|
||||
}
|
||||
}
|
||||
|
||||
boost::shared_ptr<GeometrySerializer> ifcopenshell::serializers::geometry_serializer_registry::create(const std::string& extension, const geometry_serializer_context& context) const {
|
||||
const auto iter = entries_.find(geometry_serializer_key(extension));
|
||||
if (iter == entries_.end()) {
|
||||
throw ifcopenshell::exception("No geometry serializer registered for " + extension);
|
||||
}
|
||||
return iter->second.create_(context);
|
||||
}
|
||||
|
||||
std::vector<ifcopenshell::serializers::geometry_serializer_info> ifcopenshell::serializers::geometry_serializer_registry::serializers() const {
|
||||
std::vector<geometry_serializer_info> result;
|
||||
std::set<std::string> seen_formats;
|
||||
for (const auto& pair : entries_) {
|
||||
if (!seen_formats.insert(pair.second.info_.format).second) {
|
||||
continue;
|
||||
}
|
||||
result.push_back(pair.second.info_);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* ifcopenshell::serializers::geometry_serializer_plugin_registration_symbol() {
|
||||
return "ifcopenshell_register_geometry_serializer_plugin_v1";
|
||||
}
|
||||
|
||||
ifcopenshell::plugin::metadata ifcopenshell::serializers::geometry_serializer_plugin_metadata(const std::string& format) {
|
||||
plugin::metadata metadata;
|
||||
metadata.kind_ = plugin::kind::geometry_serializer;
|
||||
metadata.id = geometry_serializer_plugin_prefix(format);
|
||||
metadata.format = boost::to_lower_copy(format);
|
||||
return metadata;
|
||||
}
|
||||
|
||||
std::filesystem::path ifcopenshell::serializers::geometry_serializer_plugin_directory() {
|
||||
return plugin::module_directory(reinterpret_cast<const void*>(&ifcopenshell::serializers::geometry_serializer_plugin_directory));
|
||||
}
|
||||
|
||||
void ifcopenshell::serializers::load_geometry_serializer_plugins(geometry_serializer_registry& registry) {
|
||||
ifcopenshell::plugin::manager manager;
|
||||
add_geometry_serializer_search_paths(manager);
|
||||
|
||||
for (const auto& path : manager.discover(geometry_serializer_plugin_prefix())) {
|
||||
ifcopenshell::plugin::module module;
|
||||
try {
|
||||
module = manager.load(path);
|
||||
} catch (const std::exception& e) {
|
||||
logger::error(e);
|
||||
continue;
|
||||
}
|
||||
if (module.meta().kind_ != ifcopenshell::plugin::kind::geometry_serializer) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto register_plugin = module.get_alias<register_geometry_serializer_plugin_fn>(geometry_serializer_plugin_registration_symbol());
|
||||
register_plugin(registry, module);
|
||||
}
|
||||
}
|
||||
|
||||
ifcopenshell::serializers::geometry_serializer_registry& ifcopenshell::serializers::geometry_serializer_registry_instance() {
|
||||
static geometry_serializer_registry registry;
|
||||
static std::once_flag once;
|
||||
std::call_once(once, load_geometry_serializer_plugins, std::ref(registry));
|
||||
return registry;
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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 IFCOPENSHELL_GEOMETRY_SERIALIZER_PLUGIN_H
|
||||
#define IFCOPENSHELL_GEOMETRY_SERIALIZER_PLUGIN_H
|
||||
|
||||
#include "../serializers/serializers_api.h"
|
||||
#include "../ifcgeom/GeometrySerializer.h"
|
||||
#include "../plugin/plugin.h"
|
||||
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <filesystem>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace serializers {
|
||||
|
||||
struct SERIALIZERS_API geometry_serializer_info {
|
||||
std::string format;
|
||||
std::vector<std::string> extensions;
|
||||
std::vector<std::string> kernel_ids;
|
||||
bool supports_triangulation = false;
|
||||
bool supports_brep = false;
|
||||
bool supports_user_element_hierarchy = false;
|
||||
bool bypass_properties = true;
|
||||
bool requires_ascii_temp_file = false;
|
||||
bool writes_final_output = false;
|
||||
};
|
||||
|
||||
struct SERIALIZERS_API geometry_serializer_context {
|
||||
std::string output_filename;
|
||||
std::string output_temp_filename;
|
||||
ifcopenshell::geometry::Settings& geometry_settings;
|
||||
const ifcopenshell::geometry::SerializerSettings& serializer_settings;
|
||||
};
|
||||
|
||||
class SERIALIZERS_API geometry_serializer_registry {
|
||||
public:
|
||||
typedef boost::function<boost::shared_ptr<GeometrySerializer>(const geometry_serializer_context&)> create_fn;
|
||||
typedef boost::function<void(geometry_serializer_context&)> configure_fn;
|
||||
|
||||
void bind(const geometry_serializer_info& info, create_fn create, configure_fn configure = configure_fn(), const ifcopenshell::plugin::module& module = ifcopenshell::plugin::module());
|
||||
bool has(const std::string& extension) const;
|
||||
const geometry_serializer_info* find(const std::string& extension) const;
|
||||
void configure(const std::string& extension, geometry_serializer_context& context) const;
|
||||
boost::shared_ptr<GeometrySerializer> create(const std::string& extension, const geometry_serializer_context& context) const;
|
||||
std::vector<geometry_serializer_info> serializers() const;
|
||||
|
||||
private:
|
||||
struct entry {
|
||||
geometry_serializer_info info_;
|
||||
create_fn create_;
|
||||
configure_fn configure_;
|
||||
ifcopenshell::plugin::module module_;
|
||||
};
|
||||
|
||||
std::map<std::string, entry> entries_;
|
||||
};
|
||||
|
||||
typedef void register_geometry_serializer_plugin_fn(geometry_serializer_registry&, const ifcopenshell::plugin::module&);
|
||||
|
||||
SERIALIZERS_API const char* geometry_serializer_plugin_registration_symbol();
|
||||
SERIALIZERS_API ifcopenshell::plugin::metadata geometry_serializer_plugin_metadata(const std::string& format);
|
||||
SERIALIZERS_API std::filesystem::path geometry_serializer_plugin_directory();
|
||||
SERIALIZERS_API void load_geometry_serializer_plugins(geometry_serializer_registry& registry);
|
||||
SERIALIZERS_API geometry_serializer_registry& geometry_serializer_registry_instance();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,67 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifdef IFOPSH_WITH_OPENCASCADE
|
||||
|
||||
#include "geometry_serializer_plugin.h"
|
||||
#include "StepSerializer.h"
|
||||
|
||||
#include <boost/dll/alias.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace serializers {
|
||||
namespace geometry_stp_plugin {
|
||||
|
||||
plugin::abi_info plugin_abi() {
|
||||
return plugin::host_abi();
|
||||
}
|
||||
|
||||
plugin::metadata plugin_metadata() {
|
||||
return geometry_serializer_plugin_metadata("stp");
|
||||
}
|
||||
|
||||
boost::shared_ptr<GeometrySerializer> create_serializer(const geometry_serializer_context& context) {
|
||||
return boost::make_shared<StepSerializer>(context.output_temp_filename, context.geometry_settings, context.serializer_settings);
|
||||
}
|
||||
|
||||
void configure_serializer(geometry_serializer_context& context) {
|
||||
context.geometry_settings.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = true;
|
||||
context.geometry_settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
|
||||
}
|
||||
|
||||
void register_plugin(geometry_serializer_registry& registry, const plugin::module& module) {
|
||||
geometry_serializer_info info;
|
||||
info.format = "stp";
|
||||
info.extensions = { ".stp" };
|
||||
info.kernel_ids = { "opencascade" };
|
||||
info.supports_brep = true;
|
||||
info.requires_ascii_temp_file = true;
|
||||
registry.bind(info, create_serializer, configure_serializer, module);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_stp_plugin::plugin_abi, ifcopenshell_plugin_abi_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_stp_plugin::plugin_metadata, ifcopenshell_plugin_metadata_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_stp_plugin::register_plugin, ifcopenshell_register_geometry_serializer_plugin_v1)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,67 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifdef IFOPSH_WITH_OPENCASCADE
|
||||
|
||||
#include "geometry_serializer_plugin.h"
|
||||
#include "SvgSerializer.h"
|
||||
|
||||
#include <boost/dll/alias.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace serializers {
|
||||
namespace geometry_svg_plugin {
|
||||
|
||||
plugin::abi_info plugin_abi() {
|
||||
return plugin::host_abi();
|
||||
}
|
||||
|
||||
plugin::metadata plugin_metadata() {
|
||||
return geometry_serializer_plugin_metadata("svg");
|
||||
}
|
||||
|
||||
boost::shared_ptr<GeometrySerializer> create_serializer(const geometry_serializer_context& context) {
|
||||
return boost::make_shared<SvgSerializer>(context.output_temp_filename, context.geometry_settings, context.serializer_settings);
|
||||
}
|
||||
|
||||
void configure_serializer(geometry_serializer_context& context) {
|
||||
context.geometry_settings.get<ifcopenshell::geometry::settings::UseElementHierarchy>().value = true;
|
||||
context.geometry_settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
|
||||
}
|
||||
|
||||
void register_plugin(geometry_serializer_registry& registry, const plugin::module& module) {
|
||||
geometry_serializer_info info;
|
||||
info.format = "svg";
|
||||
info.extensions = { ".svg" };
|
||||
info.kernel_ids = { "opencascade" };
|
||||
info.supports_brep = true;
|
||||
info.bypass_properties = false;
|
||||
registry.bind(info, create_serializer, configure_serializer, module);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_svg_plugin::plugin_abi, ifcopenshell_plugin_abi_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_svg_plugin::plugin_metadata, ifcopenshell_plugin_metadata_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_svg_plugin::register_plugin, ifcopenshell_register_geometry_serializer_plugin_v1)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,64 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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 "geometry_serializer_plugin.h"
|
||||
#include "TtlWktSerializer.h"
|
||||
|
||||
#include <boost/dll/alias.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace serializers {
|
||||
namespace geometry_ttl_plugin {
|
||||
|
||||
plugin::abi_info plugin_abi() {
|
||||
return plugin::host_abi();
|
||||
}
|
||||
|
||||
plugin::metadata plugin_metadata() {
|
||||
return geometry_serializer_plugin_metadata("ttl");
|
||||
}
|
||||
|
||||
boost::shared_ptr<GeometrySerializer> create_serializer(const geometry_serializer_context& context) {
|
||||
return boost::make_shared<TtlWktSerializer>(context.output_temp_filename, context.geometry_settings, context.serializer_settings);
|
||||
}
|
||||
|
||||
void configure_serializer(geometry_serializer_context& context) {
|
||||
context.geometry_settings.get<ifcopenshell::geometry::settings::TriangulationType>().value = ifcopenshell::geometry::settings::POLYHEDRON_WITH_HOLES;
|
||||
if (context.serializer_settings.get<ifcopenshell::geometry::settings::WktUseSection>().get()) {
|
||||
context.geometry_settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
|
||||
}
|
||||
}
|
||||
|
||||
void register_plugin(geometry_serializer_registry& registry, const plugin::module& module) {
|
||||
geometry_serializer_info info;
|
||||
info.format = "ttl";
|
||||
info.extensions = { ".ttl" };
|
||||
info.supports_triangulation = true;
|
||||
info.supports_brep = true;
|
||||
registry.bind(info, create_serializer, configure_serializer, module);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_ttl_plugin::plugin_abi, ifcopenshell_plugin_abi_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_ttl_plugin::plugin_metadata, ifcopenshell_plugin_metadata_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_ttl_plugin::register_plugin, ifcopenshell_register_geometry_serializer_plugin_v1)
|
||||
@@ -0,0 +1,62 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifdef WITH_USD
|
||||
|
||||
#include "geometry_serializer_plugin.h"
|
||||
#include "USDSerializer.h"
|
||||
|
||||
#include <boost/dll/alias.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
namespace ifcopenshell {
|
||||
namespace serializers {
|
||||
namespace geometry_usd_plugin {
|
||||
|
||||
plugin::abi_info plugin_abi() {
|
||||
return plugin::host_abi();
|
||||
}
|
||||
|
||||
plugin::metadata plugin_metadata() {
|
||||
return geometry_serializer_plugin_metadata("usd");
|
||||
}
|
||||
|
||||
boost::shared_ptr<GeometrySerializer> create_serializer(const geometry_serializer_context& context) {
|
||||
return boost::make_shared<USDSerializer>(context.output_filename, context.geometry_settings, context.serializer_settings);
|
||||
}
|
||||
|
||||
void register_plugin(geometry_serializer_registry& registry, const plugin::module& module) {
|
||||
geometry_serializer_info info;
|
||||
info.format = "usd";
|
||||
info.extensions = { ".usd", ".usda", ".usdc" };
|
||||
info.supports_triangulation = true;
|
||||
info.supports_user_element_hierarchy = true;
|
||||
info.writes_final_output = true;
|
||||
registry.bind(info, create_serializer, geometry_serializer_registry::configure_fn(), module);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_usd_plugin::plugin_abi, ifcopenshell_plugin_abi_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_usd_plugin::plugin_metadata, ifcopenshell_plugin_metadata_v1)
|
||||
BOOST_DLL_ALIAS(ifcopenshell::serializers::geometry_usd_plugin::register_plugin, ifcopenshell_register_geometry_serializer_plugin_v1)
|
||||
|
||||
#endif
|
||||
@@ -1,26 +1,10 @@
|
||||
set(document_serializer_plugin_runtime_dir "${CMAKE_BINARY_DIR}/serializers/$<CONFIG>")
|
||||
|
||||
foreach(schema ${SCHEMA_VERSIONS})
|
||||
add_library(document_serializer_xml_ifc${schema} SHARED XmlSerializer.cpp xml_plugin.cpp)
|
||||
target_link_libraries(document_serializer_xml_ifc${schema} PRIVATE plugin Serializers IfcGeom IfcParse)
|
||||
set_target_properties(document_serializer_xml_ifc${schema} PROPERTIES
|
||||
COMPILE_FLAGS "-DIfcSchema=Ifc${schema}"
|
||||
OUTPUT_NAME "document.xml.ifc${schema}"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${document_serializer_plugin_runtime_dir}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${document_serializer_plugin_runtime_dir}"
|
||||
)
|
||||
list(APPEND document_serializer_libraries document_serializer_xml_ifc${schema})
|
||||
add_document_serializer_plugin(document_serializer_xml_ifc${schema} "document.xml.ifc${schema}" SOURCES XmlSerializer.cpp xml_plugin.cpp)
|
||||
target_compile_definitions(document_serializer_xml_ifc${schema} PRIVATE IfcSchema=Ifc${schema})
|
||||
|
||||
if(WITH_GLTF)
|
||||
add_library(document_serializer_json_ifc${schema} SHARED JsonSerializer.cpp json_plugin.cpp)
|
||||
target_link_libraries(document_serializer_json_ifc${schema} PRIVATE plugin Serializers IfcGeom IfcParse)
|
||||
set_target_properties(document_serializer_json_ifc${schema} PROPERTIES
|
||||
COMPILE_FLAGS "-DIfcSchema=Ifc${schema}"
|
||||
OUTPUT_NAME "document.json.ifc${schema}"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${document_serializer_plugin_runtime_dir}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${document_serializer_plugin_runtime_dir}"
|
||||
)
|
||||
list(APPEND document_serializer_libraries document_serializer_json_ifc${schema})
|
||||
if(GLTF_SUPPORT)
|
||||
add_document_serializer_plugin(document_serializer_json_ifc${schema} "document.json.ifc${schema}" SOURCES JsonSerializer.cpp json_plugin.cpp)
|
||||
target_compile_definitions(document_serializer_json_ifc${schema} PRIVATE IfcSchema=Ifc${schema})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
|
||||
@@ -25,16 +25,16 @@
|
||||
#include "../../ifcparse/macros.h"
|
||||
|
||||
#include <boost/dll/alias.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
struct factory_t {
|
||||
JsonSerializer* operator()(ifcopenshell::file* file, const std::string& json_filename, JsonSerializer::Dialect dialect) const {
|
||||
auto* serializer = new POSTFIX_SCHEMA(JsonSerializer)(file, json_filename, dialect);
|
||||
serializer->setFile(file);
|
||||
return serializer;
|
||||
}
|
||||
};
|
||||
boost::shared_ptr<Serializer> create_serializer(const ifcopenshell::serializers::document_serializer_context& context) {
|
||||
return boost::make_shared<POSTFIX_SCHEMA(JsonSerializer)>(
|
||||
context.file,
|
||||
context.output_filename,
|
||||
static_cast<JsonSerializer::Dialect>(context.dialect));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -50,9 +50,11 @@ plugin::metadata plugin_metadata() {
|
||||
return document_serializer_plugin_metadata("json", STRINGIFY(IfcSchema));
|
||||
}
|
||||
|
||||
void register_plugin(JsonSerializerFactory::Factory& registry, const plugin::module& module) {
|
||||
factory_t factory;
|
||||
registry.bind(STRINGIFY(IfcSchema), factory, module);
|
||||
void register_plugin(document_serializer_registry& registry, const plugin::module& module) {
|
||||
document_serializer_info info;
|
||||
info.format = "json";
|
||||
info.schema_name = STRINGIFY(IfcSchema);
|
||||
registry.bind(info, create_serializer, module);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,16 +23,13 @@
|
||||
#include "../../ifcparse/macros.h"
|
||||
|
||||
#include <boost/dll/alias.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
struct factory_t {
|
||||
XmlSerializer* operator()(ifcopenshell::file* file, const std::string& xml_filename) const {
|
||||
auto* serializer = new POSTFIX_SCHEMA(XmlSerializer)(file, xml_filename);
|
||||
serializer->setFile(file);
|
||||
return serializer;
|
||||
}
|
||||
};
|
||||
boost::shared_ptr<Serializer> create_serializer(const ifcopenshell::serializers::document_serializer_context& context) {
|
||||
return boost::make_shared<POSTFIX_SCHEMA(XmlSerializer)>(context.file, context.output_filename);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -48,9 +45,11 @@ plugin::metadata plugin_metadata() {
|
||||
return document_serializer_plugin_metadata("xml", STRINGIFY(IfcSchema));
|
||||
}
|
||||
|
||||
void register_plugin(XmlSerializerFactory::Factory& registry, const plugin::module& module) {
|
||||
factory_t factory;
|
||||
registry.bind(STRINGIFY(IfcSchema), factory, module);
|
||||
void register_plugin(document_serializer_registry& registry, const plugin::module& module) {
|
||||
document_serializer_info info;
|
||||
info.format = "xml";
|
||||
info.schema_name = STRINGIFY(IfcSchema);
|
||||
registry.bind(info, create_serializer, module);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user