/******************************************************************************** * * * 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 . * * * ********************************************************************************/ #ifdef WITH_OPENCOLLADA #ifndef COLLADASERIALIZER_H #define COLLADASERIALIZER_H #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable : 4201 4512) #endif #include #include #include #include #include #ifdef _MSC_VER #pragma warning(pop) #endif #include "../ifcgeom/IfcGeomIterator.h" #include "../ifcconvert/GeometrySerializer.h" class ColladaSerializer : public GeometrySerializer { // TODO The vast amount of implement details of ColladaSerializer could be hidden to the cpp file. private: class ColladaExporter { private: class ColladaGeometries : public COLLADASW::LibraryGeometries { ColladaGeometries(const ColladaGeometries&); //N/A ColladaGeometries& operator =(const ColladaGeometries&); //N/A public: explicit ColladaGeometries(COLLADASW::StreamWriter& stream, ColladaSerializer *_serializer) : COLLADASW::LibraryGeometries(&stream) , serializer(_serializer) {} void addFloatSource(const std::string& mesh_id, const std::string& suffix, const std::vector& floats, const char* coords = "XYZ"); void write(const std::string &mesh_id, const std::string& default_material_name, const std::vector& positions, const std::vector& normals, const std::vector& faces, const std::vector& edges, const std::vector material_ids, const std::vector& materials, const std::vector& uvs); void close(); ColladaSerializer *serializer; }; class ColladaScene : public COLLADASW::LibraryVisualScenes { private: ColladaScene(const ColladaScene&); //N/A ColladaScene& operator =(const ColladaScene&); //N/A const std::string scene_id; bool scene_opened; public: ColladaScene(const std::string& scene_id, COLLADASW::StreamWriter& stream, ColladaSerializer *_serializer) : COLLADASW::LibraryVisualScenes(&stream) , scene_id(scene_id) , scene_opened(false) , serializer(_serializer) {} void add(const std::string& node_id, const std::string& node_name, const std::string& geom_name, const std::vector& material_ids, const std::vector& matrix); void write(); ColladaSerializer *serializer; }; class ColladaMaterials : public COLLADASW::LibraryMaterials { ColladaMaterials(const ColladaMaterials&); //N/A ColladaMaterials& operator =(const ColladaMaterials&); //N/A private: class ColladaEffects : public COLLADASW::LibraryEffects { ColladaEffects(const ColladaEffects&); //N/A ColladaEffects& operator =(const ColladaEffects&); //N/A public: explicit ColladaEffects(COLLADASW::StreamWriter& stream) : COLLADASW::LibraryEffects(&stream) {} void write(const IfcGeom::Material& material); void close(); ColladaSerializer *serializer; }; std::vector materials; public: explicit ColladaMaterials(COLLADASW::StreamWriter& stream, ColladaSerializer *_serializer) : COLLADASW::LibraryMaterials(&stream) , effects(stream) , serializer(_serializer) {} void add(const IfcGeom::Material& material); bool contains(const IfcGeom::Material& material); void write(); ColladaSerializer *serializer; ColladaEffects effects; }; class DeferredObject { public: std::string unique_id, representation_id, type; std::vector matrix; std::vector vertices; std::vector normals; std::vector faces; std::vector edges; std::vector material_ids; std::vector materials; std::vector material_references; std::vector uvs; DeferredObject(const std::string& unique_id, const std::string& representation_id, const std::string& type, const std::vector& matrix, const std::vector& vertices, const std::vector& normals, const std::vector& faces, const std::vector& edges, const std::vector& material_ids, const std::vector& materials, const std::vector& material_references, const std::vector& uvs) : unique_id(unique_id) , representation_id(representation_id) , type(type) , matrix(matrix) , vertices(vertices) , normals(normals) , faces(faces) , edges(edges) , material_ids(material_ids) , materials(materials) , material_references(material_references) , uvs(uvs) {} }; COLLADABU::NativeString filename; COLLADASW::StreamWriter stream; ColladaScene scene; public: ColladaExporter(const std::string& scene_name, const std::string& fn, ColladaSerializer *_serializer) : filename(fn) , stream(filename, sizeof(real_t) == sizeof(double)) // utilise Collada stream's double precision feature , geometries(stream, _serializer) , scene(scene_name, stream, _serializer) , materials(stream, _serializer) , serializer(_serializer) { } ColladaMaterials materials; ColladaSerializer *serializer; ColladaGeometries geometries; std::vector deferreds; virtual ~ColladaExporter() {} void startDocument(const std::string& unit_name, float unit_magnitude); void write(const IfcGeom::TriangulationElement* o); void endDocument(); }; ColladaExporter exporter; std::string unit_name; float unit_magnitude; public: ColladaSerializer(const std::string& dae_filename, const IfcGeom::IteratorSettings &settings) : GeometrySerializer(settings) , exporter("IfcOpenShell", dae_filename, this) { exporter.serializer = this; exporter.materials.serializer = this; exporter.materials.effects.serializer = this; exporter.geometries.serializer = this; } 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) { unit_name = name; unit_magnitude = magnitude; } void setFile(IfcParse::IfcFile*) {} }; #endif #endif