diff --git a/src/serializers/USDSerializer.cpp b/src/serializers/USDSerializer.cpp index 8be716f1e9..95d5c161fc 100644 --- a/src/serializers/USDSerializer.cpp +++ b/src/serializers/USDSerializer.cpp @@ -4,24 +4,29 @@ #include "../ifcparse/utils.h" -#include "pxr/pxr.h" -#include "pxr/usd/usd/stage.h" #include "pxr/usd/sdf/path.h" +#include "pxr/usd/gf/vec3f.h" +#include "pxr/usd/gf/rotation.h" +#include "pxr/usd/tf/token.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 "pxr/usd/usdShade/material.h" +#include "pxr/usd/usdShade/shader.h" +#include "pxr/usd/usdShade/tokens.h" +#include "pxr/usd/usdShade/materialBindingAPI.h" +#include "pxr/usd/usdShade/connectableAPI.h" + #include #include #include -USDSerializer::USDSerializer(const std::string& filename, const SerializerSettings& settings, bool read_only) +USDSerializer::USDSerializer(const std::string& filename, const SerializerSettings& settings) : WriteOnlyGeometrySerializer(settings) , filename_(filename) , settings_(settings) @@ -43,7 +48,7 @@ USDSerializer::~USDSerializer() { } -void USDSerializer::writeLighting() { +void USDSerializer::createLighting() { // create a distant light const std::string& light_path = "/World/defaultLight"; pxr::UsdLuxDistantLight::Define(stage_, pxr::SdfPath(light_path)); @@ -57,6 +62,35 @@ void USDSerializer::writeLighting() { light.CreateColorAttr().Set(pxr::GfVec3f(1.0f, 1.0f, 1.0f)); } +void USDSerializer::writeMaterial(const pxr::UsdGeomMesh& mesh,const IfcGeom::Material& style) { + std::stringstream ss; + ss << "/Looks/" << style.original_name(); + pxr::UsdShadeMaterial::Define(stage_, pxr::SdfPath(ss.str())); + pxr::UsdShadeMaterial material(stage_->GetPrimAtPath(pxr::SdfPath(ss.str()))); + pxr::UsdShadeShader shader = pxr::UsdShadeShader::Define(stage_, pxr::SdfPath(ss.str() + "/Shader")); + shader.CreateIdAttr().Set(TfToken("UsdPreviewSurface")); + + float rgba[4] { 0.18f, 0.18f, 0.18f, 1.0f }; + if (style.hasDiffuse()) + for (int i = 0; i < 3; ++i) rgba[i] = static_cast style.diffuse()[i]; + shader.CreateInput(pxr::TfToken("diffuseColor"), pxr::SdfValueTypeNames->Color3f).Set(pxr::GfVec3f(rgba[0], rgba[1], rgba[2])); + + if(style.hasTransparency()) + rgba[3] = 1.0f - style.transparency(); + shader.CreateInput(pxr::TfToken("opacity"), pxr::SdfValueTypeNames->Float).Set(rgba[3]); + + if(style.hasSpecular()) { + for (int i = 0; i < 3; ++i) rgba[i] = static_cast style.specular()[i]; + shader.CreateInput(pxr::TfToken("useSpecularWorkflow"), pxr::SdfValueTypeNames->Int).Set(1); + } else { + shader.CreateInput(pxr::TfToken("useSpecularWorkflow"), pxr::SdfValueTypeNames->Int).Set(0); + } + shader.CreateInput(pxr::TfToken("specularColor"), pxr::SdfValueTypeNames->Color3f).Set(pxr::GfVec3f(rgba[0], rgba[1], rgba[2])); + + material.CreateSurfaceOutput().ConnectToSource(shader, pxr::TfToken("surface")); + pxr::UsdShadeMaterialBindingAPI(mesh).Bind(material); +} + bool USDSerializer::ready() { return ready_; } @@ -64,7 +98,7 @@ bool USDSerializer::ready() { void USDSerializer::writeHeader() { std::stringstream ss; ss << "File generated by IfcOpenShell " << IFCOPENSHELL_VERSION; - stage_->SetMetadata("comment", ss.str()); + stage_->GetRootLayer()->SetComment(ss.str()); } void USDSerializer::write(const IfcGeom::TriangulationElement* o) { diff --git a/src/serializers/USDSerializer.h b/src/serializers/USDSerializer.h index 24428c7e60..aa50258802 100644 --- a/src/serializers/USDSerializer.h +++ b/src/serializers/USDSerializer.h @@ -35,8 +35,8 @@ private: bool ready_ = false; pxr::UsdStageRefPtr stage_; - int writeMaterial(const IfcGeom::Material& style); - void writeLighting(); + int writeMaterial(const IfcGeom::Material&); + void createLighting(); public: USDSerializer(const std::string&, const SerializerSettings&); virtual ~USDSerializer();