Support multimaterials on one mesh #44

Merged
Bogdan Nagirniak merged 11 commits from BLEN-417 into hydra-render 2023-05-24 07:07:39 +02:00
4 changed files with 46 additions and 31 deletions
Showing only changes of commit fc4da28bb9 - Show all commits

View File

@ -26,7 +26,7 @@ pxr::HdMeshTopology BlenderSceneDelegate::GetMeshTopology(pxr::SdfPath const &id
{
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText());
MeshData *m_data = mesh_data(id);
return m_data->mesh_topology();
return m_data->mesh_topology(id);
}
pxr::GfMatrix4d BlenderSceneDelegate::GetTransform(pxr::SdfPath const &id)
@ -96,7 +96,7 @@ pxr::HdPrimvarDescriptorVector BlenderSceneDelegate::GetPrimvarDescriptors(
pxr::SdfPath BlenderSceneDelegate::GetMaterialId(pxr::SdfPath const &rprim_id)
{
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", rprim_id.GetText());
return mesh_data(rprim_id)->material_id();
return mesh_data(rprim_id)->material_id(rprim_id);
}
pxr::VtValue BlenderSceneDelegate::GetMaterialResource(pxr::SdfPath const &id)
@ -125,7 +125,7 @@ bool BlenderSceneDelegate::GetVisible(pxr::SdfPath const &id)
bool BlenderSceneDelegate::GetDoubleSided(pxr::SdfPath const &id)
{
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText());
return mesh_data(id)->double_sided();
return mesh_data(id)->double_sided(id);
}
pxr::HdCullStyle BlenderSceneDelegate::GetCullStyle(pxr::SdfPath const &id)
@ -510,12 +510,8 @@ void BlenderSceneDelegate::remove_unused_objects()
std::set<pxr::SdfPath> available_materials;
for (auto &it : objects_) {
MeshData *m_data = dynamic_cast<MeshData *>(it.second.get());
if (!m_data) {
continue;
}
pxr::SdfPath mat_id = m_data->material_id();
if (!mat_id.IsEmpty()) {
available_materials.insert(mat_id);
if (m_data) {
m_data->available_materials(available_materials);
}
}
for (auto &it : instancers_) {

View File

@ -214,10 +214,7 @@ void InstancerData::check_remove(std::set<std::string> &available_objects)
void InstancerData::available_materials(std::set<pxr::SdfPath> &paths) const
{
for (auto &it : mesh_instances_) {
pxr::SdfPath mat_id = ((MeshData *)it.second.data.get())->material_id();
if (!mat_id.IsEmpty()) {
paths.insert(mat_id);
}
((MeshData *)it.second.data.get())->available_materials(paths);
}
}

View File

@ -125,9 +125,9 @@ bool MeshData::update_visibility()
return ret;
}
pxr::HdMeshTopology MeshData::mesh_topology() const
pxr::HdMeshTopology MeshData::mesh_topology(pxr::SdfPath const &id) const
{
const MaterialMesh &m = material_meshes_[0];
const SubMesh &m = sub_meshes_[0];
return pxr::HdMeshTopology(pxr::PxOsdOpenSubdivTokens->none,
pxr::HdTokens->rightHanded,
m.face_vertex_counts,
@ -157,18 +157,18 @@ pxr::HdPrimvarDescriptorVector MeshData::primvar_descriptors(
return primvars;
}
pxr::SdfPath MeshData::material_id() const
pxr::SdfPath MeshData::material_id(pxr::SdfPath const &id) const
{
const MaterialMesh &m = material_meshes_[0];
const SubMesh &m = sub_meshes_[0];
if (!m.mat_data) {
return pxr::SdfPath();
}
return m.mat_data->prim_id;
}
bool MeshData::double_sided() const
bool MeshData::double_sided(pxr::SdfPath const &id) const
{
const MaterialMesh &m = material_meshes_[0];
const SubMesh &m = sub_meshes_[0];
if (m.mat_data) {
return m.mat_data->double_sided;
}
@ -177,7 +177,7 @@ bool MeshData::double_sided() const
void MeshData::update_double_sided(MaterialData *mat_data)
{
MaterialMesh &m = material_meshes_[0];
SubMesh &m = sub_meshes_[0];
if (m.mat_data == mat_data) {
ID_LOG(2, "");
@ -186,6 +186,15 @@ void MeshData::update_double_sided(MaterialData *mat_data)
}
}
void MeshData::available_materials(std::set<pxr::SdfPath> &paths) const
{
for (auto &m : sub_meshes_) {
if (m.mat_data && !m.mat_data->prim_id.IsEmpty()) {
paths.insert(m.mat_data->prim_id);
}
}
}
void MeshData::write_mesh(Mesh *mesh)
{
vertices_.clear();
@ -206,10 +215,12 @@ void MeshData::write_mesh(Mesh *mesh)
}
/* material meshes */
material_meshes_.clear();
sub_meshes_.clear();
int mat_count = BKE_object_material_count_eval((Object *)id);
for (int i = 0; i < std::max(mat_count, 1); ++i) {
material_meshes_.push_back(MaterialMesh());
SubMesh m;
m.mat_index = i;
sub_meshes_.push_back(m);
}
const int *material_indices = BKE_mesh_material_indices(mesh);
@ -220,13 +231,22 @@ void MeshData::write_mesh(Mesh *mesh)
int mat_ind = material_indices ? material_indices[looptri_polys[i]] : 0;
const MLoopTri &lt = looptris[i];
MaterialMesh &m = material_meshes_[mat_ind];
SubMesh &m = sub_meshes_[mat_ind];
m.face_vertex_counts.push_back(3);
m.face_vertex_indices.push_back(corner_verts[lt.tri[0]]);
m.face_vertex_indices.push_back(corner_verts[lt.tri[1]]);
m.face_vertex_indices.push_back(corner_verts[lt.tri[2]]);
}
for (auto it = sub_meshes_.begin(); it != sub_meshes_.end();) {
if (it->face_vertex_counts.empty()) {
it = sub_meshes_.erase(it);
}
else {
++it;
}
}
write_normals(mesh);
write_uv_maps(mesh);
write_material();
@ -235,12 +255,12 @@ void MeshData::write_mesh(Mesh *mesh)
void MeshData::write_material()
{
Object *object = (Object *)id;
for (int i = 0; i < material_meshes_.size(); ++i) {
MaterialMesh &m = material_meshes_[i];
for (int i = 0; i < sub_meshes_.size(); ++i) {
SubMesh &m = sub_meshes_[i];
if (m.face_vertex_counts.empty()) {
continue;
}
Material *mat = BKE_object_material_get_eval(object, i);
Material *mat = BKE_object_material_get_eval(object, m.mat_index);
if (!mat) {
m.mat_data = nullptr;
continue;

View File

@ -14,9 +14,10 @@
namespace blender::render::hydra {
class MeshData : public ObjectData {
struct MaterialMesh {
struct SubMesh {
pxr::VtIntArray face_vertex_counts;
pxr::VtIntArray face_vertex_indices;
int mat_index = 0;
MaterialData *mat_data = nullptr;
};
@ -31,11 +32,12 @@ class MeshData : public ObjectData {
pxr::VtValue get_data(pxr::TfToken const &key) const override;
bool update_visibility() override;
pxr::HdMeshTopology mesh_topology() const;
pxr::HdMeshTopology mesh_topology(pxr::SdfPath const &id) const;
pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation) const;
pxr::SdfPath material_id() const;
bool double_sided() const;
pxr::SdfPath material_id(pxr::SdfPath const &id) const;
bool double_sided(pxr::SdfPath const &id) const;
void update_double_sided(MaterialData *mat_data);
void available_materials(std::set<pxr::SdfPath> &paths) const;
pxr::HdCullStyle cull_style = pxr::HdCullStyleBackUnlessDoubleSided;
@ -49,7 +51,7 @@ class MeshData : public ObjectData {
pxr::VtVec2fArray uvs_;
pxr::VtVec3fArray normals_;
std::vector<MaterialMesh> material_meshes_;
std::vector<SubMesh> sub_meshes_;
};
} // namespace blender::render::hydra