Dust3D项目实训三 | 基于model类的三维模型构建分析

本文分析了model模块,包括model.h和model.cpp文件。详细介绍了用于构建三维模型的结构体TriangulatedFace,以及Model类的成员变量和方法,如构造函数、颜色重置等。Model类中包含了纹理图像、法向属性、金属度、粗糙度等信息,并提供了相应的访问和设置方法。此外,还展示了如何通过构造函数复制模型数据。
摘要由CSDN通过智能技术生成

2021SC@SDUSC

目录 

分析概括

model.h分析

三维模型构造三角面的结构体

模型类

model.cpp分析

构造函数

重置颜色


分析概括

基于上周分析的object类 的基础上,本周继续进行modle模块的分析,主要分析modle.h与modle.cpp。

model.h分析

三维模型构造三角面的结构体

struct TriangulatedFace
{//结构体:三角面
    int indices[3];//三位索引
    QColor color;//颜色
};

模型类

model类变量详解

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++;
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值