mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-19 22:50:21 +00:00
material subsets
This commit is contained in:
@@ -46,33 +46,40 @@ void USDSerializer::createLighting() {
|
|||||||
light.CreateColorAttr().Set(pxr::GfVec3f(1.0f, 1.0f, 1.0f));
|
light.CreateColorAttr().Set(pxr::GfVec3f(1.0f, 1.0f, 1.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
void USDSerializer::writeMaterial(const pxr::UsdGeomMesh& mesh,const IfcGeom::Material& style) {
|
std::vector<pxr::UsdShadeMaterial> USDSerializer::createMaterials(const pxr::UsdGeomMesh& mesh,
|
||||||
std::string path("/Looks/" + sanitize(style.original_name()));
|
const std::vector<IfcGeom::Material>& styles)
|
||||||
auto material = pxr::UsdShadeMaterial::Define(stage_, pxr::SdfPath(path));
|
{
|
||||||
auto shader = pxr::UsdShadeShader::Define(stage_, pxr::SdfPath(path + "/Shader"));
|
std::vector<pxr::UsdShadeMaterial> materials {};
|
||||||
shader.CreateIdAttr().Set(pxr::TfToken("UsdPreviewSurface"));
|
|
||||||
|
|
||||||
float rgba[4] { 0.18f, 0.18f, 0.18f, 1.0f };
|
for(auto style : styles) {
|
||||||
if (style.hasDiffuse())
|
std::string path("/Looks/" + sanitize(style.original_name()));
|
||||||
for (int i = 0; i < 3; ++i)
|
auto material = pxr::UsdShadeMaterial::Define(stage_, pxr::SdfPath(path));
|
||||||
rgba[i] = static_cast<float>(style.diffuse()[i]);
|
auto shader = pxr::UsdShadeShader::Define(stage_, pxr::SdfPath(path + "/Shader"));
|
||||||
shader.CreateInput(pxr::TfToken("diffuseColor"), pxr::SdfValueTypeNames->Color3f).Set(pxr::GfVec3f(rgba[0], rgba[1], rgba[2]));
|
shader.CreateIdAttr().Set(pxr::TfToken("UsdPreviewSurface"));
|
||||||
|
|
||||||
if(style.hasTransparency())
|
float rgba[4] { 0.18f, 0.18f, 0.18f, 1.0f };
|
||||||
rgba[3] -= style.transparency();
|
if (style.hasDiffuse())
|
||||||
shader.CreateInput(pxr::TfToken("opacity"), pxr::SdfValueTypeNames->Float).Set(rgba[3]);
|
for (int i = 0; i < 3; ++i)
|
||||||
|
rgba[i] = static_cast<float>(style.diffuse()[i]);
|
||||||
|
shader.CreateInput(pxr::TfToken("diffuseColor"), pxr::SdfValueTypeNames->Color3f).Set(pxr::GfVec3f(rgba[0], rgba[1], rgba[2]));
|
||||||
|
|
||||||
if(style.hasSpecular()) {
|
if(style.hasTransparency())
|
||||||
for (int i = 0; i < 3; ++i)
|
rgba[3] -= style.transparency();
|
||||||
rgba[i] = static_cast<float>(style.specular()[i]);
|
shader.CreateInput(pxr::TfToken("opacity"), pxr::SdfValueTypeNames->Float).Set(rgba[3]);
|
||||||
shader.CreateInput(pxr::TfToken("useSpecularWorkflow"), pxr::SdfValueTypeNames->Int).Set(1);
|
|
||||||
} else {
|
if(style.hasSpecular()) {
|
||||||
shader.CreateInput(pxr::TfToken("useSpecularWorkflow"), pxr::SdfValueTypeNames->Int).Set(0);
|
for (int i = 0; i < 3; ++i)
|
||||||
|
rgba[i] = static_cast<float>(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.ConnectableAPI(), pxr::TfToken("surface"));
|
||||||
|
materials.push_back(material);
|
||||||
}
|
}
|
||||||
shader.CreateInput(pxr::TfToken("specularColor"), pxr::SdfValueTypeNames->Color3f).Set(pxr::GfVec3f(rgba[0], rgba[1], rgba[2]));
|
return materials;
|
||||||
|
|
||||||
material.CreateSurfaceOutput().ConnectToSource(shader.ConnectableAPI(), pxr::TfToken("surface"));
|
|
||||||
pxr::UsdShadeMaterialBindingAPI(mesh).Bind(material);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool USDSerializer::ready() {
|
bool USDSerializer::ready() {
|
||||||
@@ -92,12 +99,12 @@ void USDSerializer::write(const IfcGeom::TriangulationElement* o) {
|
|||||||
if ( mesh.material_ids().empty() || verts.empty() || faces.empty() )
|
if ( mesh.material_ids().empty() || verts.empty() || faces.empty() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::string name = o->name() + std::to_string(o->id());
|
std::string name = o->name();
|
||||||
if(name.empty()) {
|
if(name.empty()) {
|
||||||
name = "Unnamed_" + std::to_string(unnamed_count_);
|
name = "Unnamed_" + std::to_string(unnamed_count_);
|
||||||
unnamed_count_++;
|
unnamed_count_++;
|
||||||
} else {
|
} else {
|
||||||
name = sanitize(name);
|
name = sanitize(name) + std::to_string(o->id());
|
||||||
}
|
}
|
||||||
pxr::UsdGeomMesh usd_mesh = pxr::UsdGeomMesh::Define(stage_, pxr::SdfPath("/World/" + name));
|
pxr::UsdGeomMesh usd_mesh = pxr::UsdGeomMesh::Define(stage_, pxr::SdfPath("/World/" + name));
|
||||||
|
|
||||||
@@ -119,7 +126,21 @@ void USDSerializer::write(const IfcGeom::TriangulationElement* o) {
|
|||||||
normals.push_back(pxr::GfVec3f(static_cast<float>(*(it++)), static_cast<float>(*(it++)), static_cast<float>(*(it++))));
|
normals.push_back(pxr::GfVec3f(static_cast<float>(*(it++)), static_cast<float>(*(it++)), static_cast<float>(*(it++))));
|
||||||
usd_mesh.CreateNormalsAttr().Set(normals);
|
usd_mesh.CreateNormalsAttr().Set(normals);
|
||||||
|
|
||||||
writeMaterial(usd_mesh, mesh.materials()[0]);
|
auto materials = createMaterials(usd_mesh, mesh.materials());
|
||||||
|
pxr::UsdShadeMaterialBindingAPI material_api(usd_mesh);
|
||||||
|
if(materials.size() > 1) {
|
||||||
|
auto material_ids = mesh.material_ids();
|
||||||
|
std::vector<pxr::VtArray<int>> subsets(materials.size());
|
||||||
|
for(int i = 0; i < material_ids.size(); ++i) {
|
||||||
|
subsets[material_ids[i]].push_back(i);
|
||||||
|
}
|
||||||
|
for(std::size_t i = 0; i < subsets.size(); ++i){
|
||||||
|
auto subset = material_api.CreateMaterialBindSubset(pxr::TfToken("subset_" + std::to_string(i)), subsets[i]);
|
||||||
|
pxr::UsdShadeMaterialBindingAPI(subset).Bind(materials[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
material_api.Bind(materials[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void USDSerializer::finalize() {
|
void USDSerializer::finalize() {
|
||||||
|
|||||||
@@ -59,17 +59,14 @@ private:
|
|||||||
std::map<std::string, pxr::UsdGeomMesh> meshes_;
|
std::map<std::string, pxr::UsdGeomMesh> meshes_;
|
||||||
std::map<std::string, pxr::UsdShadeMaterial> materials_;
|
std::map<std::string, pxr::UsdShadeMaterial> materials_;
|
||||||
|
|
||||||
std::string sanitize(std::string s) {
|
inline std::string sanitize(std::string s) {
|
||||||
std::replace_if(s.begin(), s.end(),
|
std::replace_if(s.begin(), s.end(),
|
||||||
[](char c) { return c == ' ' || c == '.' || c == ','
|
[](char c) { return c > 122 || c < 48 || (c > 57 && c < 65) || (c > 90 && c < 97); },
|
||||||
|| c == ';' || c == ':' || c == '/'
|
|
||||||
|| c == '-' || c == '+' || c == '"'
|
|
||||||
|| c > 127; },
|
|
||||||
'_');
|
'_');
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeMaterial(const pxr::UsdGeomMesh&, const IfcGeom::Material&);
|
std::vector<pxr::UsdShadeMaterial> createMaterials(const pxr::UsdGeomMesh&, const std::vector<IfcGeom::Material>&);
|
||||||
void createLighting();
|
void createLighting();
|
||||||
public:
|
public:
|
||||||
USDSerializer(const std::string&, const SerializerSettings&);
|
USDSerializer(const std::string&, const SerializerSettings&);
|
||||||
|
|||||||
Reference in New Issue
Block a user