1010#include " pxr/usd/usdGeom/tokens.h"
1111#include " pxr/usd/usdGeom/scope.h"
1212#include " pxr/usd/usdLux/distantLight.h"
13- #include " pxr/usd/usdShade/material.h"
1413#include " pxr/usd/usdShade/shader.h"
1514#include " pxr/usd/usdShade/tokens.h"
1615#include " pxr/usd/usdShade/materialBindingAPI.h"
1716#include " pxr/usd/usdShade/connectableAPI.h"
1817
19- #include < string>
20- #include < sstream>
21-
22- USDSerializer::USDSerializer (const std::string& filename, const SerializerSettings& settings)
23- : WriteOnlyGeometrySerializer(settings)
24- , filename_(filename)
18+ USDSerializer::USDSerializer (const std::string& out_filename, const SerializerSettings& settings):
19+ WriteOnlyGeometrySerializer(settings),
20+ filename_(out_filename)
2521{
2622 // create a new stage
27- stage_ = pxr::UsdStage::CreateNew (filename + " .usda" );
28-
29- // create root xform prim 'World'
23+ stage_ = pxr::UsdStage::CreateNew (filename_ + " .usda" );
24+
3025 pxr::UsdGeomXform::Define (stage_, pxr::SdfPath (" /World" ));
3126 pxr::UsdGeomScope::Define (stage_, pxr::SdfPath (" /Looks" ));
3227 createLighting ();
@@ -52,69 +47,83 @@ void USDSerializer::createLighting() {
5247}
5348
5449void USDSerializer::writeMaterial (const pxr::UsdGeomMesh& mesh,const IfcGeom::Material& style) {
55- std::stringstream ss;
56- ss << " /Looks/" << style.original_name ();
57- pxr::UsdShadeMaterial::Define (stage_, pxr::SdfPath (ss.str ()));
58- pxr::UsdShadeMaterial material (stage_->GetPrimAtPath (pxr::SdfPath (ss.str ())));
59- pxr::UsdShadeShader shader = pxr::UsdShadeShader::Define (stage_, pxr::SdfPath (ss.str () + " /Shader" ));
50+ std::string path (" /Looks/" + sanitize (style.original_name ()));
51+ auto material = pxr::UsdShadeMaterial::Define (stage_, pxr::SdfPath (path));
52+ auto shader = pxr::UsdShadeShader::Define (stage_, pxr::SdfPath (path + " /Shader" ));
6053 shader.CreateIdAttr ().Set (pxr::TfToken (" UsdPreviewSurface" ));
6154
6255 float rgba[4 ] { 0 .18f , 0 .18f , 0 .18f , 1 .0f };
6356 if (style.hasDiffuse ())
64- for (int i = 0 ; i < 3 ; ++i) rgba[i] = static_cast <float >(style.diffuse ()[i]);
57+ for (int i = 0 ; i < 3 ; ++i)
58+ rgba[i] = static_cast <float >(style.diffuse ()[i]);
6559 shader.CreateInput (pxr::TfToken (" diffuseColor" ), pxr::SdfValueTypeNames->Color3f ).Set (pxr::GfVec3f (rgba[0 ], rgba[1 ], rgba[2 ]));
6660
6761 if (style.hasTransparency ())
68- rgba[3 ] = 1 . 0f - style.transparency ();
62+ rgba[3 ] -= style.transparency ();
6963 shader.CreateInput (pxr::TfToken (" opacity" ), pxr::SdfValueTypeNames->Float ).Set (rgba[3 ]);
7064
7165 if (style.hasSpecular ()) {
72- for (int i = 0 ; i < 3 ; ++i) rgba[i] = static_cast <float >(style.specular ()[i]);
66+ for (int i = 0 ; i < 3 ; ++i)
67+ rgba[i] = static_cast <float >(style.specular ()[i]);
7368 shader.CreateInput (pxr::TfToken (" useSpecularWorkflow" ), pxr::SdfValueTypeNames->Int ).Set (1 );
7469 } else {
7570 shader.CreateInput (pxr::TfToken (" useSpecularWorkflow" ), pxr::SdfValueTypeNames->Int ).Set (0 );
7671 }
7772 shader.CreateInput (pxr::TfToken (" specularColor" ), pxr::SdfValueTypeNames->Color3f ).Set (pxr::GfVec3f (rgba[0 ], rgba[1 ], rgba[2 ]));
7873
79- // material.CreateSurfaceOutput().ConnectToSource(shader, pxr::TfToken("surface"));
80- // pxr::UsdShadeMaterialBindingAPI(mesh).Bind(material);
74+ material.CreateSurfaceOutput ().ConnectToSource (shader. ConnectableAPI () , pxr::TfToken (" surface" ));
75+ pxr::UsdShadeMaterialBindingAPI (mesh).Bind (material);
8176}
8277
8378bool USDSerializer::ready () {
8479 return ready_;
8580}
8681
8782void USDSerializer::writeHeader () {
88- std::stringstream ss;
89- ss << " File generated by IfcOpenShell " << IFCOPENSHELL_VERSION;
90- stage_->GetRootLayer ()->SetComment (ss.str ());
83+ stage_->GetRootLayer ()->SetComment (" File generated by IfcOpenShell " + std::string (IFCOPENSHELL_VERSION));
9184}
9285
9386void USDSerializer::write (const IfcGeom::TriangulationElement* o) {
9487 const IfcGeom::Representation::Triangulation& mesh = o->geometry ();
95- if ( mesh.material_ids ().empty () || mesh.verts ().empty () || mesh.faces ().empty () )
88+ auto verts = mesh.verts ();
89+ auto faces = mesh.faces ();
90+ const std::vector<double >& m = o->transformation ().matrix ().data ();
91+
92+ if ( mesh.material_ids ().empty () || verts.empty () || faces.empty () )
9693 return ;
9794
98- std::stringstream ss (" /World/" );
99- ss << mesh.id ();
100- pxr::UsdGeomMesh usd_mesh = pxr::UsdGeomMesh::Define (stage_, pxr::SdfPath (ss.str ()));
101- const std::vector<double >& m = o->transformation ().matrix ().data ();
95+ std::string name = o->name () + std::to_string (o->id ());
96+ if (name.empty ()) {
97+ name = " Unnamed_" + std::to_string (unnamed_count_);
98+ unnamed_count_++;
99+ } else {
100+ name = sanitize (name);
101+ }
102+ pxr::UsdGeomMesh usd_mesh = pxr::UsdGeomMesh::Define (stage_, pxr::SdfPath (" /World/" + name));
103+
104+ usd_mesh.AddTranslateOp ().Set (pxr::GfVec3d (m[9 ], m[10 ], m[11 ]));
102105
103- const int vcount = (int ) mesh.verts ().size () / 3 ;
104- pxr::VtVec3dArray points;
105- for ( std::vector<double >::const_iterator it = mesh.verts ().begin (); it != mesh.verts ().end (); ) {
106- points.push_back (pxr::GfVec3d (*(it++), *(it++), *(it++)));
106+ pxr::VtVec3fArray points;
107+ for (std::size_t i = 0 ; i < verts.size (); i+=3 ) {
108+ points.push_back (pxr::GfVec3f (static_cast <float >(verts[i] * m[0 ] + verts[i+1 ] * m[3 ] + verts[i+2 ] * m[6 ]),
109+ static_cast <float >(verts[i] * m[1 ] + verts[i+1 ] * m[4 ] + verts[i+2 ] * m[7 ]),
110+ static_cast <float >(verts[i] * m[2 ] + verts[i+1 ] * m[5 ] + verts[i+2 ] * m[8 ])));
107111 }
108112 usd_mesh.CreatePointsAttr ().Set (points);
109- usd_mesh.CreateFaceVertexIndicesAttr ().Set (usd_utils::toVtArray (mesh.faces ()));
110- const int fcount = (int ) mesh.faces ().size () / 3 ;
111- usd_mesh.CreateFaceVertexCountsAttr ().Set (pxr::VtArray<int >(fcount, 3 ));
112- usd_mesh.CreateNormalsAttr ().Set (usd_utils::toVtArray (mesh.normals ()));
113113
114+ usd_mesh.CreateFaceVertexIndicesAttr ().Set (usd_utils::toVtArray (faces));
115+ usd_mesh.CreateFaceVertexCountsAttr ().Set (pxr::VtArray<int >((int ) faces.size () / 3 , 3 ));
116+
117+ pxr::VtVec3fArray normals;
118+ for (std::vector<double >::const_iterator it = mesh.normals ().begin (); it != mesh.normals ().end ();)
119+ normals.push_back (pxr::GfVec3f (static_cast <float >(*(it++)), static_cast <float >(*(it++)), static_cast <float >(*(it++))));
120+ usd_mesh.CreateNormalsAttr ().Set (normals);
121+
122+ writeMaterial (usd_mesh, mesh.materials ()[0 ]);
114123}
115124
116125void USDSerializer::finalize () {
117- stage_->GetRootLayer ()-> Save ();
126+ stage_->Save ();
118127}
119128
120129#endif // WITH_USD
0 commit comments