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
2 changed files with 64 additions and 68 deletions
Showing only changes of commit ca20ec82a6 - Show all commits

View File

@ -43,9 +43,9 @@ void MeshData::init()
Review

The order is important here?

The order is important here?
Review

No

No
void MeshData::insert() void MeshData::insert()
{ {
if (face_vertex_counts_.empty()) { //if (face_vertex_counts_.empty()) {
return; // return;
} //}
ID_LOG(2, ""); ID_LOG(2, "");
scene_delegate_->GetRenderIndex().InsertRprim( scene_delegate_->GetRenderIndex().InsertRprim(
@ -72,7 +72,7 @@ void MeshData::update()
} }
else { else {
if (id->recalc & ID_RECALC_SHADING) { if (id->recalc & ID_RECALC_SHADING) {
write_material(nullptr); write_material();
bits |= pxr::HdChangeTracker::DirtyMaterialId | pxr::HdChangeTracker::DirtyDoubleSided; bits |= pxr::HdChangeTracker::DirtyMaterialId | pxr::HdChangeTracker::DirtyDoubleSided;
} }
if (id->recalc & ID_RECALC_TRANSFORM) { if (id->recalc & ID_RECALC_TRANSFORM) {
@ -90,11 +90,11 @@ void MeshData::update()
return; return;
} }
if (face_vertex_counts_.empty()) { //if (face_vertex_counts_.empty()) {
/* Remove prim without faces */ // /* Remove prim without faces */
remove(); // remove();
return; // return;
} //}
ID_LOG(2, ""); ID_LOG(2, "");
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(prim_id, bits); scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(prim_id, bits);
} }
@ -127,10 +127,11 @@ bool MeshData::update_visibility()
pxr::HdMeshTopology MeshData::mesh_topology() const pxr::HdMeshTopology MeshData::mesh_topology() const
{ {
const MaterialMesh &m = material_meshes_[0];
return pxr::HdMeshTopology(pxr::PxOsdOpenSubdivTokens->none, return pxr::HdMeshTopology(pxr::PxOsdOpenSubdivTokens->none,
pxr::HdTokens->rightHanded, pxr::HdTokens->rightHanded,
face_vertex_counts_, m.face_vertex_counts,
face_vertex_indices_); m.face_vertex_indices);
} }
pxr::HdPrimvarDescriptorVector MeshData::primvar_descriptors( pxr::HdPrimvarDescriptorVector MeshData::primvar_descriptors(
@ -158,23 +159,27 @@ pxr::HdPrimvarDescriptorVector MeshData::primvar_descriptors(
pxr::SdfPath MeshData::material_id() const pxr::SdfPath MeshData::material_id() const
{ {
if (!mat_data_) { const MaterialMesh &m = material_meshes_[0];
if (!m.mat_data) {
return pxr::SdfPath(); return pxr::SdfPath();
} }
return mat_data_->prim_id; return m.mat_data->prim_id;
} }
bool MeshData::double_sided() const bool MeshData::double_sided() const
{ {
if (mat_data_) { const MaterialMesh &m = material_meshes_[0];
return mat_data_->double_sided; if (m.mat_data) {
return m.mat_data->double_sided;
} }
return true; return true;
} }
void MeshData::update_double_sided(MaterialData *mat_data) void MeshData::update_double_sided(MaterialData *mat_data)
{ {
if (mat_data_ == mat_data) { MaterialMesh &m = material_meshes_[0];
if (m.mat_data == mat_data) {
ID_LOG(2, ""); ID_LOG(2, "");
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty( scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(
prim_id, pxr::HdChangeTracker::DirtyDoubleSided); prim_id, pxr::HdChangeTracker::DirtyDoubleSided);
@ -183,12 +188,9 @@ void MeshData::update_double_sided(MaterialData *mat_data)
void MeshData::write_mesh(Mesh *mesh) void MeshData::write_mesh(Mesh *mesh)
{ {
face_vertex_counts_.clear();
face_vertex_indices_.clear();
vertices_.clear(); vertices_.clear();
normals_.clear(); normals_.clear();
uvs_.clear(); uvs_.clear();
face_material_indices_.clear();
BKE_mesh_calc_normals_split(mesh); BKE_mesh_calc_normals_split(mesh);
int tris_len = BKE_mesh_runtime_looptri_len(mesh); int tris_len = BKE_mesh_runtime_looptri_len(mesh);
@ -196,20 +198,6 @@ void MeshData::write_mesh(Mesh *mesh)
return; return;
} }
blender::Span<MLoopTri> loopTris = mesh->looptris();
/* face_vertex_counts */
face_vertex_counts_ = pxr::VtIntArray(tris_len, 3);
/* face_vertex_indices */
blender::Span<int> corner_verts = mesh->corner_verts();
face_vertex_indices_.reserve(loopTris.size() * 3);
for (MLoopTri lt : loopTris) {
face_vertex_indices_.push_back(corner_verts[lt.tri[0]]);
face_vertex_indices_.push_back(corner_verts[lt.tri[1]]);
face_vertex_indices_.push_back(corner_verts[lt.tri[2]]);
}
/* vertices */ /* vertices */
vertices_.reserve(mesh->totvert); vertices_.reserve(mesh->totvert);
blender::Span<blender::float3> verts = mesh->vert_positions(); blender::Span<blender::float3> verts = mesh->vert_positions();
@ -217,42 +205,53 @@ void MeshData::write_mesh(Mesh *mesh)
vertices_.push_back(pxr::GfVec3f(v.x, v.y, v.z)); vertices_.push_back(pxr::GfVec3f(v.x, v.y, v.z));
} }
write_normals(mesh); /* material meshes */
write_uv_maps(mesh); material_meshes_.clear();
write_material(mesh); 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());
} }
void MeshData::write_material(Mesh *mesh)
{
Object *object = (Object *)id;
Material *mat = nullptr;
if (BKE_object_material_count_eval(object) > 0) {
mat = BKE_object_material_get_eval(object, object->actcol);
}
if (!mat) {
mat_data_ = nullptr;
return;
}
pxr::SdfPath p_id = scene_delegate_->material_prim_id(mat);
mat_data_ = scene_delegate_->material_data(p_id);
if (!mat_data_) {
scene_delegate_->materials_[p_id] = std::make_unique<MaterialData>(scene_delegate_, mat, p_id);
mat_data_ = scene_delegate_->material_data(p_id);
mat_data_->init();
mat_data_->insert();
}
if (mesh) {
face_material_indices_.clear();
const int *material_indices = BKE_mesh_material_indices(mesh); const int *material_indices = BKE_mesh_material_indices(mesh);
const int *looptri_polys = BKE_mesh_runtime_looptri_polys_ensure(mesh); const int *looptri_polys = BKE_mesh_runtime_looptri_polys_ensure(mesh);
int poly_ind; blender::Span<int> corner_verts = mesh->corner_verts();
blender::Span<MLoopTri> loopTris = mesh->looptris(); blender::Span<MLoopTri> looptris = mesh->looptris();
for (size_t i = 0; i < loopTris.size(); ++i) { for (size_t i = 0; i < looptris.size(); ++i) {
poly_ind = looptri_polys[i]; int mat_ind = material_indices ? material_indices[looptri_polys[i]] : 0;
face_material_indices_.push_back(material_indices[poly_ind]);
const MLoopTri &lt = looptris[i];
MaterialMesh &m = material_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]]);
}
write_normals(mesh);
write_uv_maps(mesh);
write_material();
}
void MeshData::write_material()
{
Object *object = (Object *)id;
for (int i = 0; i < material_meshes_.size(); ++i) {
MaterialMesh &m = material_meshes_[i];
if (m.face_vertex_counts.empty()) {
continue;
}
Material *mat = BKE_object_material_get_eval(object, i);
if (!mat) {
m.mat_data = nullptr;
continue;
}
pxr::SdfPath p_id = scene_delegate_->material_prim_id(mat);
m.mat_data = scene_delegate_->material_data(p_id);
if (!m.mat_data) {
scene_delegate_->materials_[p_id] = std::make_unique<MaterialData>(scene_delegate_, mat, p_id);
m.mat_data = scene_delegate_->material_data(p_id);
m.mat_data->init();
m.mat_data->insert();
} }
} }
} }

View File

@ -41,18 +41,15 @@ class MeshData : public ObjectData {
private: private:
void write_mesh(Mesh *mesh); void write_mesh(Mesh *mesh);
void write_material(Mesh *mesh); void write_material();
void write_uv_maps(Mesh *mesh); void write_uv_maps(Mesh *mesh);
void write_normals(Mesh *mesh); void write_normals(Mesh *mesh);
pxr::VtIntArray face_vertex_counts_;
pxr::VtIntArray face_vertex_indices_;
pxr::VtVec3fArray vertices_; pxr::VtVec3fArray vertices_;
pxr::VtVec2fArray uvs_; pxr::VtVec2fArray uvs_;
pxr::VtVec3fArray normals_; pxr::VtVec3fArray normals_;
pxr::VtIntArray face_material_indices_; std::vector<MaterialMesh> material_meshes_;
MaterialData *mat_data_ = nullptr;
}; };
} // namespace blender::render::hydra } // namespace blender::render::hydra