2021SC@SDUSC
目录
分析概括
基于上周分析的object类 的基础上,本周继续进行modle模块的分析,主要分析modle.h与modle.cpp。
model.h分析
三维模型构造三角面的结构体
struct TriangulatedFace
{//结构体:三角面
int indices[3];//三位索引
QColor color;//颜色
};
模型类
m_triangleVertices | 三角形构造点 |
m_edgeVertices | 边缘三角形点 |
m_toolVertices | 定位辅助点 |
m_textureImage | 纹理图像 |
m_normalMapImage | 法向属性变量 |
m_metalnessRoughnessAmbientOcclusionImage | 三角形面片属性变量 |
class Model
{//模型类
public:
//构造函数
Model(const std::vector<QVector3D> &vertices, const std::vector<std::vector<size_t>> &triangles,
const std::vector<std::vector<QVector3D>> &triangleVertexNormals,
const QColor &color=Qt::white,//初始化颜色为白色
float metalness=0.0,//初始化金属性为0
float roughness=0.0);//初始化粗糙度为0
Model(Object &object);
Model();//函数为空
//析构函数
~Model();
//以下函数均为返回相关变量的作用,以便在类外调用相关变量
ShaderVertex *triangleVertices();
int triangleVertexCount();
ShaderVertex *edgeVertices();
int edgeVertexCount();
ShaderVertex *toolVertices();
int toolVertexCount();
const std::vector<QVector3D> &vertices();
const std::vector<std::vector<size_t>> &faces();
const std::vector<QVector3D> &triangulatedVertices();
const std::vector<TriangulatedFace> &triangulatedFaces();
void setTextureImage(QImage *textureImage);
const QImage *textureImage();
void setNormalMapImage(QImage *normalMapImage);
const QImage *normalMapImage();
const QImage *metalnessRoughnessAmbientOcclusionImage();
void setMetalnessRoughnessAmbientOcclusionImage(QImage *image);
bool hasMetalnessInImage();
void setHasMetalnessInImage(bool hasInImage);
bool hasRoughnessInImage();
void setHasRoughnessInImage(bool hasInImage);
bool hasAmbientOcclusionInImage();
void setHasAmbientOcclusionInImage(bool hasInImage);
static float m_defaultMetalness;
static float m_defaultRoughness;
void exportAsObj(const QString &filename);
void exportAsObj(QTextStream *textStream);
void updateTool(ShaderVertex *toolVertices, int vertexNum);
void updateEdges(ShaderVertex *edgeVertices, int edgeVertexCount);
void updateTriangleVertices(ShaderVertex *triangleVertices, int triangleVertexCount);
quint64 meshId() const;//quint64为64位有符号数据类型
void setMeshId(quint64 id);
void removeColor();
private:
ShaderVertex *m_triangleVertices = nullptr;//三角形顶点初始化属性为空
int m_triangleVertexCount = 0;//三角形顶点数
ShaderVertex *m_edgeVertices = nullptr;//边缘点初始化属性为空
int m_edgeVertexCount = 0;//边缘点数
ShaderVertex *m_toolVertices = nullptr;
int m_toolVertexCount = 0;
std::vector<QVector3D> m_vertices;
std::vector<std::vector<size_t>> m_faces;
std::vector<QVector3D> m_triangulatedVertices;
std::vector<TriangulatedFace> m_triangulatedFaces;//三角面
QImage *m_textureImage = nullptr;//纹理颜色
QImage *m_normalMapImage = nullptr;//法线颜色
QImage *m_metalnessRoughnessAmbientOcclusionImage = nullptr;//金属性、粗糙度、环境遮蔽后颜色
bool m_hasMetalnessInImage = false;//是否存在金属性颜色
bool m_hasRoughnessInImage = false;//是否存在粗糙度颜色
bool m_hasAmbientOcclusionInImage = false;//是否存在金属性、粗糙度、环境遮蔽后颜色
quint64 m_meshId = 0;
};
model.cpp分析
构造函数
model类型的构造函数主要用来初始化this指针为函数中的mesh变量
Model::Model(const Model &mesh) ://构造函数
m_triangleVertices(nullptr),
m_triangleVertexCount(0),
m_edgeVertices(nullptr),
m_edgeVertexCount(0),
m_textureImage(nullptr)
{
if (nullptr != mesh.m_triangleVertices &&
mesh.m_triangleVertexCount > 0) {
//如果存在三角形
this->m_triangleVertices = new ShaderVertex[mesh.m_triangleVertexCount];
this->m_triangleVertexCount = mesh.m_triangleVertexCount;
for (int i = 0; i < mesh.m_triangleVertexCount; i++)
this->m_triangleVertices[i] = mesh.m_triangleVertices[i];//将mesh的各个点属性赋值给this指针
}
if (nullptr != mesh.m_edgeVertices &&
mesh.m_edgeVertexCount > 0) {
//如果边缘点非空
this->m_edgeVertices = new ShaderVertex[mesh.m_edgeVertexCount];
this->m_edgeVertexCount = mesh.m_edgeVertexCount;
for (int i = 0; i < mesh.m_edgeVertexCount; i++)
this->m_edgeVertices[i] = mesh.m_edgeVertices[i];//将mesh的各个边缘点属性赋值给this指针
}
if (nullptr != mesh.m_toolVertices &&
mesh.m_toolVertexCount > 0) {
//如果绘制的定位辅助点非空
this->m_toolVertices = new ShaderVertex[mesh.m_toolVertexCount];
this->m_toolVertexCount = mesh.m_toolVertexCount;
for (int i = 0; i < mesh.m_toolVertexCount; i++)
this->m_toolVertices[i] = mesh.m_toolVertices[i];
}
if (nullptr != mesh.m_textureImage) {
//如果纹理图像非空
this->m_textureImage = new QImage(*mesh.m_textureImage);
}
if (nullptr != mesh.m_normalMapImage) {
//如果法线图像非空
this->m_normalMapImage = new QImage(*mesh.m_normalMapImage);
}
if (nullptr != mesh.m_metalnessRoughnessAmbientOcclusionImage) {
this->m_metalnessRoughnessAmbientOcclusionImage = new QImage(*mesh.m_metalnessRoughnessAmbientOcclusionImage);
this->m_hasMetalnessInImage = mesh.m_hasMetalnessInImage;
this->m_hasRoughnessInImage = mesh.m_hasRoughnessInImage;
this->m_hasAmbientOcclusionInImage = mesh.m_hasAmbientOcclusionInImage;
}
this->m_vertices = mesh.m_vertices;
this->m_faces = mesh.m_faces;
this->m_triangulatedVertices = mesh.m_triangulatedVertices;
this->m_triangulatedFaces = mesh.m_triangulatedFaces;
this->m_meshId = mesh.meshId();
}
重置颜色
removeColor函数主要用来
void Model::removeColor()//重置删除颜色
{//初始化纹理颜色、法向颜色、金属性、粗糙度、环境遮蔽后颜色为空
delete this->m_textureImage;
this->m_textureImage = nullptr;
delete this->m_normalMapImage;
this->m_normalMapImage = nullptr;
delete this->m_metalnessRoughnessAmbientOcclusionImage;
this->m_metalnessRoughnessAmbientOcclusionImage = nullptr;
//初始化不存在金属性颜色、不存在粗糙度颜色、不存在金属性、粗糙度、环境遮蔽后颜色
this->m_hasMetalnessInImage = false;
this->m_hasRoughnessInImage = false;
this->m_hasAmbientOcclusionInImage = false;
//将每一个三角形顶点颜色初始化为白色
for (int i = 0; i < this->m_triangleVertexCount; ++i) {
auto &vertex = this->m_triangleVertices[i];
vertex.colorR = 1.0;
vertex.colorG = 1.0;
vertex.colorB = 1.0;
}
}
Model::Model(Object &object) :
m_triangleVertices(nullptr),
m_triangleVertexCount(0),
m_edgeVertices(nullptr),
m_edgeVertexCount(0),
m_textureImage(nullptr)
{
m_meshId = object.meshId;
m_vertices = object.vertices;
m_faces = object.triangleAndQuads;
m_triangleVertexCount = object.triangles.size() * 3;
m_triangleVertices = new ShaderVertex[m_triangleVertexCount];
int destIndex = 0;
const auto triangleVertexNormals = object.triangleVertexNormals();
const auto triangleVertexUvs = object.triangleVertexUvs();
const auto triangleTangents = object.triangleTangents();
const QVector3D defaultNormal = QVector3D(0, 0, 0);
const QVector2D defaultUv = QVector2D(0, 0);
const QVector3D defaultTangent = QVector3D(0, 0, 0);
for (size_t i = 0; i < object.triangles.size(); ++i) {
const auto &triangleColor = &object.triangleColors[i];
for (auto j = 0; j < 3; j++) {
int vertexIndex = object.triangles[i][j];
const QVector3D *srcVert = &object.vertices[vertexIndex];
const QVector3D *srcNormal = &defaultNormal;
if (triangleVertexNormals)
srcNormal = &(*triangleVertexNormals)[i][j];
const QVector2D *srcUv = &defaultUv;
if (triangleVertexUvs)
srcUv = &(*triangleVertexUvs)[i][j];
const QVector3D *srcTangent = &defaultTangent;
if (triangleTangents)
srcTangent = &(*triangleTangents)[i];
ShaderVertex *dest = &m_triangleVertices[destIndex];
dest->colorR = triangleColor->redF();
dest->colorG = triangleColor->greenF();
dest->colorB = triangleColor->blueF();
dest->alpha = triangleColor->alphaF();
dest->posX = srcVert->x();
dest->posY = srcVert->y();
dest->posZ = srcVert->z();
dest->texU = srcUv->x();
dest->texV = srcUv->y();
dest->normX = srcNormal->x();
dest->normY = srcNormal->y();
dest->normZ = srcNormal->z();
dest->metalness = m_defaultMetalness;
dest->roughness = m_defaultRoughness;
dest->tangentX = srcTangent->x();
dest->tangentY = srcTangent->y();
dest->tangentZ = srcTangent->z();
destIndex++;
}
}
size_t edgeCount = 0;
for (const auto &face: object.triangleAndQuads) {
edgeCount += face.size();
}
m_edgeVertexCount = edgeCount * 2;
m_edgeVertices = new ShaderVertex[m_edgeVertexCount];
size_t edgeVertexIndex = 0;
for (size_t faceIndex = 0; faceIndex < object.triangleAndQuads.size(); ++faceIndex) {
const auto &face = object.triangleAndQuads[faceIndex];
for (size_t i = 0; i < face.size(); ++i) {
for (size_t x = 0; x < 2; ++x) {
size_t sourceIndex = face[(i + x) % face.size()];
const QVector3D *srcVert = &object.vertices[sourceIndex];
ShaderVertex *dest = &m_edgeVertices[edgeVertexIndex];
memset(dest, 0, sizeof(ShaderVertex));
dest->colorR = 0.0;
dest->colorG = 0.0;
dest->colorB = 0.0;
dest->alpha = 1.0;
dest->posX = srcVert->x();
dest->posY = srcVert->y();
dest->posZ = srcVert->z();
dest->metalness = m_defaultMetalness;
dest->roughness = m_defaultRoughness;
edgeVertexIndex++;
}
}
}
}