forked from blender/blender
Support multimaterials on one mesh #44
@ -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_) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 < = 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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user