diff --git a/src/serializers/USDSerializer.cpp b/src/serializers/USDSerializer.cpp new file mode 100644 index 0000000000..8be716f1e9 --- /dev/null +++ b/src/serializers/USDSerializer.cpp @@ -0,0 +1,95 @@ +#ifdef WITH_USD + +#include "USDSerializer.h" + +#include "../ifcparse/utils.h" + +#include "pxr/pxr.h" +#include "pxr/usd/usd/stage.h" +#include "pxr/usd/sdf/path.h" +#include "pxr/usd/usdGeom/xform.h" +#include "pxr/usd/usdGeom/xformOp.h" +#include "pxr/usd/usdGeom/mesh.h" +#include "pxr/usd/usdGeom/tokens.h" +#include "pxr/usd/usdGeom/scope.h" +#include "pxr/usd/usdLux/distantLight.h" +#include "pxr/usd/gf/vec3f.h" +#include "pxr/usd/gf/rotation.h" + +#include +#include +#include + + +USDSerializer::USDSerializer(const std::string& filename, const SerializerSettings& settings, bool read_only) + : WriteOnlyGeometrySerializer(settings) + , filename_(filename) + , settings_(settings) +{ + // create a new stage + stage_ = pxr::UsdStage::CreateNew(filename + ".usda"); + if( !settings().get(SerializerSettings::USE_Y_UP) ) + stage_->SetDefaultPrim(pxr::UsdGeomXform::Define(stage_, pxr::SdfPath("/"), pxr::UsdGeomTokens->z)); + else + stage_->SetDefaultPrim(pxr::UsdGeomXform::Define(stage_, pxr::SdfPath("/"), pxr::UsdGeomTokens->y)); + // create root xform prim 'World' + pxr::UsdGeomXform::Define(stage_, pxr::SdfPath("/World")); + pxr::UsdGeomScope::Define(stage_, pxr::SdfPath("/Looks")); + createLighting(); + ready_ = true; +} + +USDSerializer::~USDSerializer() { + +} + +void USDSerializer::writeLighting() { + // create a distant light + const std::string& light_path = "/World/defaultLight"; + pxr::UsdLuxDistantLight::Define(stage_, pxr::SdfPath(light_path)); + // set the light's orientation + pxr::UsdGeomXform xform(stage_->GetPrimAtPath(pxr::SdfPath(light_path))); + pxr::GfVec3f light_direction(0.0f, 0.0f, -1.0f); + xform.AddRotateOp(pxr::UsdGeomXformOp::PrecisionFloat, pxr::UsdGeomXformOp::TypeRotateXYZ).Set(pxr::GfRotation(pxr::GfVec3f(0.0f, 1.0f, 0.0f), light_direction).GetQuaternion()); + // set the light's color + pxr::UsdLuxDistantLight light(stage_->GetPrimAtPath(pxr::SdfPath(light_path))); + light.CreateIntensityAttr().Set(1000.0f); + light.CreateColorAttr().Set(pxr::GfVec3f(1.0f, 1.0f, 1.0f)); +} + +bool USDSerializer::ready() { + return ready_; +} + +void USDSerializer::writeHeader() { + std::stringstream ss; + ss << "File generated by IfcOpenShell " << IFCOPENSHELL_VERSION; + stage_->SetMetadata("comment", ss.str()); +} + +void USDSerializer::write(const IfcGeom::TriangulationElement* o) { + if ( o->geometry().material_ids().empty() ) + return; + + std:sstringstream ss("/World/"); + ss << o->geometry().id(); + pxr::UsdGeomMesh::Define(stage_, pxr::SdfPath(ss.str())); + const IfcGeom::Representation::Triangulation& mesh = o->geometry(); + const std::vector& m = o->transformation().matrix().data(); + + const int vcount = (int)mesh.verts().size() / 3; + for ( std::vector::const_iterator it = mesh.verts().begin(); it != mesh.verts().end(); ) { + const double x = *(it++); + const double y = *(it++); + const double z = *(it++); + + + } + +} + +void USDSerializer::finalize() { + stage_->GetRootLayer()->Save(); +} + +#endif // WITH_USD \ No newline at end of file diff --git a/src/serializers/USDSerializer.h b/src/serializers/USDSerializer.h new file mode 100644 index 0000000000..24428c7e60 --- /dev/null +++ b/src/serializers/USDSerializer.h @@ -0,0 +1,55 @@ +/******************************************************************************** + * * + * 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 . * + * * + ********************************************************************************/ + +#ifndef USDSERIALIZER_H +#define USDSERIALIZER_H + +#ifdef WITH_USD + +#include "../serializers/serializers_api.h" +#include "../ifcgeom_schema_agnostic/GeometrySerializer.h" + +#include "pxr/pxr.h" +#include "pxr/usd/usd/stage.h" + + +class SERIALIZERS_API USDSerializer : public WriteOnlyGeometrySerializer { +private: + std::string filename_; + bool ready_ = false; + pxr::UsdStageRefPtr stage_; + + int writeMaterial(const IfcGeom::Material& style); + void writeLighting(); +public: + USDSerializer(const std::string&, const SerializerSettings&); + virtual ~USDSerializer(); + bool ready(); + void writeHeader(); + void write(const IfcGeom::TriangulationElement*); + void write(const IfcGeom::BRepElement*) {} + void finalize(); + bool isTesselated() const { return true; } + void setUnitNameAndMagnitude(const std::string&, float) {} + void setFile(IfcParse::IfcFile*) {} +}; + +#endif + +#endif \ No newline at end of file