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());
|
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText());
|
||||||
MeshData *m_data = mesh_data(id);
|
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)
|
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)
|
pxr::SdfPath BlenderSceneDelegate::GetMaterialId(pxr::SdfPath const &rprim_id)
|
||||||
{
|
{
|
||||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", rprim_id.GetText());
|
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)
|
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)
|
bool BlenderSceneDelegate::GetDoubleSided(pxr::SdfPath const &id)
|
||||||
{
|
{
|
||||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText());
|
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)
|
pxr::HdCullStyle BlenderSceneDelegate::GetCullStyle(pxr::SdfPath const &id)
|
||||||
@ -510,12 +510,8 @@ void BlenderSceneDelegate::remove_unused_objects()
|
|||||||
std::set<pxr::SdfPath> available_materials;
|
std::set<pxr::SdfPath> available_materials;
|
||||||
for (auto &it : objects_) {
|
for (auto &it : objects_) {
|
||||||
MeshData *m_data = dynamic_cast<MeshData *>(it.second.get());
|
MeshData *m_data = dynamic_cast<MeshData *>(it.second.get());
|
||||||
if (!m_data) {
|
if (m_data) {
|
||||||
continue;
|
m_data->available_materials(available_materials);
|
||||||
}
|
|
||||||
pxr::SdfPath mat_id = m_data->material_id();
|
|
||||||
if (!mat_id.IsEmpty()) {
|
|
||||||
available_materials.insert(mat_id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto &it : instancers_) {
|
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
|
void InstancerData::available_materials(std::set<pxr::SdfPath> &paths) const
|
||||||
{
|
{
|
||||||
for (auto &it : mesh_instances_) {
|
for (auto &it : mesh_instances_) {
|
||||||
pxr::SdfPath mat_id = ((MeshData *)it.second.data.get())->material_id();
|
((MeshData *)it.second.data.get())->available_materials(paths);
|
||||||
if (!mat_id.IsEmpty()) {
|
|
||||||
paths.insert(mat_id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,9 +125,9 @@ bool MeshData::update_visibility()
|
|||||||
return ret;
|
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,
|
return pxr::HdMeshTopology(pxr::PxOsdOpenSubdivTokens->none,
|
||||||
pxr::HdTokens->rightHanded,
|
pxr::HdTokens->rightHanded,
|
||||||
m.face_vertex_counts,
|
m.face_vertex_counts,
|
||||||
@ -157,18 +157,18 @@ pxr::HdPrimvarDescriptorVector MeshData::primvar_descriptors(
|
|||||||
return primvars;
|
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) {
|
if (!m.mat_data) {
|
||||||
return pxr::SdfPath();
|
return pxr::SdfPath();
|
||||||
}
|
}
|
||||||
return m.mat_data->prim_id;
|
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) {
|
if (m.mat_data) {
|
||||||
return m.mat_data->double_sided;
|
return m.mat_data->double_sided;
|
||||||
}
|
}
|
||||||
@ -177,7 +177,7 @@ bool MeshData::double_sided() const
|
|||||||
|
|
||||||
void MeshData::update_double_sided(MaterialData *mat_data)
|
void MeshData::update_double_sided(MaterialData *mat_data)
|
||||||
{
|
{
|
||||||
MaterialMesh &m = material_meshes_[0];
|
SubMesh &m = sub_meshes_[0];
|
||||||
|
|
||||||
if (m.mat_data == mat_data) {
|
if (m.mat_data == mat_data) {
|
||||||
ID_LOG(2, "");
|
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)
|
void MeshData::write_mesh(Mesh *mesh)
|
||||||
{
|
{
|
||||||
vertices_.clear();
|
vertices_.clear();
|
||||||
@ -206,10 +215,12 @@ void MeshData::write_mesh(Mesh *mesh)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* material meshes */
|
/* material meshes */
|
||||||
material_meshes_.clear();
|
sub_meshes_.clear();
|
||||||
int mat_count = BKE_object_material_count_eval((Object *)id);
|
int mat_count = BKE_object_material_count_eval((Object *)id);
|
||||||
for (int i = 0; i < std::max(mat_count, 1); ++i) {
|
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);
|
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;
|
int mat_ind = material_indices ? material_indices[looptri_polys[i]] : 0;
|
||||||
|
|
||||||
const MLoopTri < = looptris[i];
|
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_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[0]]);
|
||||||
m.face_vertex_indices.push_back(corner_verts[lt.tri[1]]);
|
m.face_vertex_indices.push_back(corner_verts[lt.tri[1]]);
|
||||||
m.face_vertex_indices.push_back(corner_verts[lt.tri[2]]);
|
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_normals(mesh);
|
||||||
write_uv_maps(mesh);
|
write_uv_maps(mesh);
|
||||||
write_material();
|
write_material();
|
||||||
@ -235,12 +255,12 @@ void MeshData::write_mesh(Mesh *mesh)
|
|||||||
void MeshData::write_material()
|
void MeshData::write_material()
|
||||||
{
|
{
|
||||||
Object *object = (Object *)id;
|
Object *object = (Object *)id;
|
||||||
for (int i = 0; i < material_meshes_.size(); ++i) {
|
for (int i = 0; i < sub_meshes_.size(); ++i) {
|
||||||
MaterialMesh &m = material_meshes_[i];
|
SubMesh &m = sub_meshes_[i];
|
||||||
if (m.face_vertex_counts.empty()) {
|
if (m.face_vertex_counts.empty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Material *mat = BKE_object_material_get_eval(object, i);
|
Material *mat = BKE_object_material_get_eval(object, m.mat_index);
|
||||||
if (!mat) {
|
if (!mat) {
|
||||||
m.mat_data = nullptr;
|
m.mat_data = nullptr;
|
||||||
continue;
|
continue;
|
||||||
|
@ -14,9 +14,10 @@
|
|||||||
namespace blender::render::hydra {
|
namespace blender::render::hydra {
|
||||||
|
|
||||||
class MeshData : public ObjectData {
|
class MeshData : public ObjectData {
|
||||||
struct MaterialMesh {
|
struct SubMesh {
|
||||||
pxr::VtIntArray face_vertex_counts;
|
pxr::VtIntArray face_vertex_counts;
|
||||||
pxr::VtIntArray face_vertex_indices;
|
pxr::VtIntArray face_vertex_indices;
|
||||||
|
int mat_index = 0;
|
||||||
MaterialData *mat_data = nullptr;
|
MaterialData *mat_data = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -31,11 +32,12 @@ class MeshData : public ObjectData {
|
|||||||
pxr::VtValue get_data(pxr::TfToken const &key) const override;
|
pxr::VtValue get_data(pxr::TfToken const &key) const override;
|
||||||
bool update_visibility() 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::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation) const;
|
||||||
pxr::SdfPath material_id() const;
|
pxr::SdfPath material_id(pxr::SdfPath const &id) const;
|
||||||
bool double_sided() const;
|
bool double_sided(pxr::SdfPath const &id) const;
|
||||||
void update_double_sided(MaterialData *mat_data);
|
void update_double_sided(MaterialData *mat_data);
|
||||||
|
void available_materials(std::set<pxr::SdfPath> &paths) const;
|
||||||
|
|
||||||
pxr::HdCullStyle cull_style = pxr::HdCullStyleBackUnlessDoubleSided;
|
pxr::HdCullStyle cull_style = pxr::HdCullStyleBackUnlessDoubleSided;
|
||||||
|
|
||||||
@ -49,7 +51,7 @@ class MeshData : public ObjectData {
|
|||||||
pxr::VtVec2fArray uvs_;
|
pxr::VtVec2fArray uvs_;
|
||||||
pxr::VtVec3fArray normals_;
|
pxr::VtVec3fArray normals_;
|
||||||
|
|
||||||
std::vector<MaterialMesh> material_meshes_;
|
std::vector<SubMesh> sub_meshes_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace blender::render::hydra
|
} // namespace blender::render::hydra
|
||||||
|
Loading…
Reference in New Issue
Block a user