forked from blender/blender
Support multimaterials on one mesh #44
@ -43,9 +43,9 @@ void MeshData::init()
|
|||||||
|
|
||||||
|
|||||||
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 < = 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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user
The order is important here?
No