2018-04-26 02:23:22 +00:00
|
|
|
#include <assert.h>
|
2018-05-07 17:16:58 +00:00
|
|
|
#include "meshloader.h"
|
2018-03-10 06:57:14 +00:00
|
|
|
#include "meshlite.h"
|
2018-04-01 14:21:47 +00:00
|
|
|
#include "theme.h"
|
2018-04-26 02:23:22 +00:00
|
|
|
#include "positionmap.h"
|
2018-03-10 06:57:14 +00:00
|
|
|
|
2018-03-20 07:56:49 +00:00
|
|
|
#define MAX_VERTICES_PER_FACE 100
|
|
|
|
|
2018-05-07 17:16:58 +00:00
|
|
|
MeshLoader::MeshLoader(void *meshlite, int meshId, int triangulatedMeshId, QColor modelColor, const std::vector<QColor> *triangleColors) :
|
2018-05-10 09:16:22 +00:00
|
|
|
m_triangleVertices(nullptr),
|
2018-03-19 13:56:10 +00:00
|
|
|
m_triangleVertexCount(0),
|
2018-05-10 09:16:22 +00:00
|
|
|
m_edgeVertices(nullptr),
|
|
|
|
m_edgeVertexCount(0),
|
|
|
|
m_textureImage(nullptr)
|
2018-03-10 06:57:14 +00:00
|
|
|
{
|
2018-03-19 13:56:10 +00:00
|
|
|
int edgeVertexPositionCount = meshlite_get_vertex_count(meshlite, meshId);
|
|
|
|
GLfloat *edgeVertexPositions = new GLfloat[edgeVertexPositionCount * 3];
|
|
|
|
int loadedEdgeVertexPositionItemCount = meshlite_get_vertex_position_array(meshlite, meshId, edgeVertexPositions, edgeVertexPositionCount * 3);
|
2018-03-10 06:57:14 +00:00
|
|
|
|
2018-03-20 07:56:49 +00:00
|
|
|
int offset = 0;
|
|
|
|
while (offset < loadedEdgeVertexPositionItemCount) {
|
|
|
|
QVector3D position = QVector3D(edgeVertexPositions[offset], edgeVertexPositions[offset + 1], edgeVertexPositions[offset + 2]);
|
|
|
|
m_vertices.push_back(position);
|
|
|
|
offset += 3;
|
|
|
|
}
|
|
|
|
int faceCount = meshlite_get_face_count(meshlite, meshId);
|
|
|
|
int *faceVertexNumAndIndices = new int[faceCount * (1 + MAX_VERTICES_PER_FACE)];
|
|
|
|
int loadedFaceVertexNumAndIndicesItemCount = meshlite_get_face_index_array(meshlite, meshId, faceVertexNumAndIndices, faceCount * (1 + MAX_VERTICES_PER_FACE));
|
|
|
|
offset = 0;
|
|
|
|
while (offset < loadedFaceVertexNumAndIndicesItemCount) {
|
|
|
|
int indicesNum = faceVertexNumAndIndices[offset++];
|
|
|
|
assert(indicesNum >= 0 && indicesNum <= MAX_VERTICES_PER_FACE);
|
|
|
|
std::vector<int> face;
|
|
|
|
for (int i = 0; i < indicesNum && offset < loadedFaceVertexNumAndIndicesItemCount; i++) {
|
|
|
|
int index = faceVertexNumAndIndices[offset++];
|
|
|
|
assert(index >= 0 && index < loadedEdgeVertexPositionItemCount);
|
|
|
|
face.push_back(index);
|
|
|
|
}
|
|
|
|
m_faces.push_back(face);
|
|
|
|
}
|
|
|
|
delete[] faceVertexNumAndIndices;
|
|
|
|
faceVertexNumAndIndices = NULL;
|
|
|
|
|
2018-03-19 13:56:10 +00:00
|
|
|
int edgeCount = meshlite_get_halfedge_count(meshlite, meshId);
|
|
|
|
int *edgeIndices = new int[edgeCount * 2];
|
|
|
|
int loadedEdgeVertexIndexItemCount = meshlite_get_halfedge_index_array(meshlite, meshId, edgeIndices, edgeCount * 2);
|
|
|
|
GLfloat *edgeNormals = new GLfloat[edgeCount * 3];
|
|
|
|
int loadedEdgeNormalItemCount = meshlite_get_halfedge_normal_array(meshlite, meshId, edgeNormals, edgeCount * 3);
|
|
|
|
|
|
|
|
m_edgeVertexCount = edgeCount * 2;
|
|
|
|
m_edgeVertices = new Vertex[m_edgeVertexCount * 3];
|
|
|
|
for (int i = 0; i < edgeCount; i++) {
|
|
|
|
int firstIndex = i * 2;
|
|
|
|
for (int j = 0; j < 2; j++) {
|
|
|
|
assert(firstIndex + j < loadedEdgeVertexIndexItemCount);
|
|
|
|
int posIndex = edgeIndices[firstIndex + j] * 3;
|
|
|
|
assert(posIndex < loadedEdgeVertexPositionItemCount);
|
|
|
|
Vertex *v = &m_edgeVertices[firstIndex + j];
|
|
|
|
v->posX = edgeVertexPositions[posIndex + 0];
|
|
|
|
v->posY = edgeVertexPositions[posIndex + 1];
|
|
|
|
v->posZ = edgeVertexPositions[posIndex + 2];
|
|
|
|
assert(firstIndex + 2 < loadedEdgeNormalItemCount);
|
|
|
|
v->normX = edgeNormals[firstIndex + 0];
|
|
|
|
v->normY = edgeNormals[firstIndex + 1];
|
|
|
|
v->normZ = edgeNormals[firstIndex + 2];
|
2018-04-01 14:21:47 +00:00
|
|
|
v->colorR = 0.0;
|
|
|
|
v->colorG = 0.0;
|
|
|
|
v->colorB = 0.0;
|
2018-05-10 09:16:22 +00:00
|
|
|
v->texU = 0.0;
|
|
|
|
v->texV = 0.0;
|
2018-03-19 13:56:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-26 02:23:22 +00:00
|
|
|
int triangleMesh = -1 == triangulatedMeshId ? meshlite_triangulate(meshlite, meshId) : triangulatedMeshId;
|
2018-03-19 13:56:10 +00:00
|
|
|
|
|
|
|
int triangleVertexPositionCount = meshlite_get_vertex_count(meshlite, triangleMesh);
|
|
|
|
GLfloat *triangleVertexPositions = new GLfloat[triangleVertexPositionCount * 3];
|
|
|
|
int loadedTriangleVertexPositionItemCount = meshlite_get_vertex_position_array(meshlite, triangleMesh, triangleVertexPositions, triangleVertexPositionCount * 3);
|
|
|
|
|
2018-04-26 02:23:22 +00:00
|
|
|
offset = 0;
|
|
|
|
while (offset < loadedTriangleVertexPositionItemCount) {
|
|
|
|
QVector3D position = QVector3D(triangleVertexPositions[offset], triangleVertexPositions[offset + 1], triangleVertexPositions[offset + 2]);
|
|
|
|
m_triangulatedVertices.push_back(position);
|
|
|
|
offset += 3;
|
|
|
|
}
|
|
|
|
|
2018-03-19 13:56:10 +00:00
|
|
|
int triangleCount = meshlite_get_face_count(meshlite, triangleMesh);
|
2018-03-10 06:57:14 +00:00
|
|
|
int *triangleIndices = new int[triangleCount * 3];
|
2018-03-19 13:56:10 +00:00
|
|
|
int loadedTriangleVertexIndexItemCount = meshlite_get_triangle_index_array(meshlite, triangleMesh, triangleIndices, triangleCount * 3);
|
2018-04-26 02:23:22 +00:00
|
|
|
|
2018-03-19 13:56:10 +00:00
|
|
|
GLfloat *triangleNormals = new GLfloat[triangleCount * 3];
|
|
|
|
int loadedTriangleNormalItemCount = meshlite_get_triangle_normal_array(meshlite, triangleMesh, triangleNormals, triangleCount * 3);
|
2018-03-10 06:57:14 +00:00
|
|
|
|
2018-04-26 02:23:22 +00:00
|
|
|
float modelR = modelColor.redF();
|
|
|
|
float modelG = modelColor.greenF();
|
|
|
|
float modelB = modelColor.blueF();
|
2018-03-19 13:56:10 +00:00
|
|
|
m_triangleVertexCount = triangleCount * 3;
|
|
|
|
m_triangleVertices = new Vertex[m_triangleVertexCount * 3];
|
2018-03-10 06:57:14 +00:00
|
|
|
for (int i = 0; i < triangleCount; i++) {
|
|
|
|
int firstIndex = i * 3;
|
2018-04-26 02:23:22 +00:00
|
|
|
float useColorR = modelR;
|
|
|
|
float useColorG = modelG;
|
|
|
|
float useColorB = modelB;
|
|
|
|
if (triangleColors && i < (int)triangleColors->size()) {
|
|
|
|
QColor triangleColor = (*triangleColors)[i];
|
|
|
|
useColorR = triangleColor.redF();
|
|
|
|
useColorG = triangleColor.greenF();
|
|
|
|
useColorB = triangleColor.blueF();
|
|
|
|
}
|
|
|
|
TriangulatedFace triangulatedFace;
|
|
|
|
triangulatedFace.color.setRedF(useColorR);
|
|
|
|
triangulatedFace.color.setGreenF(useColorG);
|
|
|
|
triangulatedFace.color.setBlueF(useColorB);
|
2018-03-10 06:57:14 +00:00
|
|
|
for (int j = 0; j < 3; j++) {
|
2018-03-19 13:56:10 +00:00
|
|
|
assert(firstIndex + j < loadedTriangleVertexIndexItemCount);
|
2018-03-10 06:57:14 +00:00
|
|
|
int posIndex = triangleIndices[firstIndex + j] * 3;
|
2018-03-19 13:56:10 +00:00
|
|
|
assert(posIndex < loadedTriangleVertexPositionItemCount);
|
2018-04-26 02:23:22 +00:00
|
|
|
triangulatedFace.indicies[j] = triangleIndices[firstIndex + j];
|
2018-03-19 13:56:10 +00:00
|
|
|
Vertex *v = &m_triangleVertices[firstIndex + j];
|
|
|
|
v->posX = triangleVertexPositions[posIndex + 0];
|
|
|
|
v->posY = triangleVertexPositions[posIndex + 1];
|
|
|
|
v->posZ = triangleVertexPositions[posIndex + 2];
|
|
|
|
assert(firstIndex + 2 < loadedTriangleNormalItemCount);
|
|
|
|
v->normX = triangleNormals[firstIndex + 0];
|
|
|
|
v->normY = triangleNormals[firstIndex + 1];
|
|
|
|
v->normZ = triangleNormals[firstIndex + 2];
|
2018-04-26 02:23:22 +00:00
|
|
|
v->colorR = useColorR;
|
|
|
|
v->colorG = useColorG;
|
|
|
|
v->colorB = useColorB;
|
2018-03-10 06:57:14 +00:00
|
|
|
}
|
2018-04-26 02:23:22 +00:00
|
|
|
m_triangulatedFaces.push_back(triangulatedFace);
|
2018-03-10 06:57:14 +00:00
|
|
|
}
|
|
|
|
|
2018-03-19 13:56:10 +00:00
|
|
|
delete[] triangleVertexPositions;
|
2018-03-10 06:57:14 +00:00
|
|
|
delete[] triangleIndices;
|
2018-03-19 13:56:10 +00:00
|
|
|
delete[] triangleNormals;
|
|
|
|
|
|
|
|
delete[] edgeVertexPositions;
|
|
|
|
delete[] edgeIndices;
|
|
|
|
delete[] edgeNormals;
|
2018-03-10 06:57:14 +00:00
|
|
|
}
|
|
|
|
|
2018-06-11 14:24:25 +00:00
|
|
|
MeshLoader::MeshLoader(const MeshLoader &mesh) :
|
2018-05-10 09:16:22 +00:00
|
|
|
m_triangleVertices(nullptr),
|
|
|
|
m_triangleVertexCount(0),
|
|
|
|
m_edgeVertices(nullptr),
|
|
|
|
m_edgeVertexCount(0),
|
|
|
|
m_textureImage(nullptr)
|
|
|
|
{
|
2018-06-11 14:24:25 +00:00
|
|
|
if (nullptr != mesh.m_triangleVertices &&
|
|
|
|
mesh.m_triangleVertexCount > 0) {
|
|
|
|
this->m_triangleVertices = new Vertex[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];
|
2018-05-10 09:16:22 +00:00
|
|
|
}
|
2018-06-11 14:24:25 +00:00
|
|
|
if (nullptr != mesh.m_edgeVertices &&
|
|
|
|
mesh.m_edgeVertexCount > 0) {
|
|
|
|
this->m_edgeVertices = new Vertex[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];
|
|
|
|
}
|
|
|
|
if (nullptr != mesh.m_textureImage) {
|
|
|
|
this->m_textureImage = new QImage(*mesh.m_textureImage);
|
|
|
|
}
|
|
|
|
this->m_vertices = mesh.m_vertices;
|
|
|
|
this->m_faces = mesh.m_faces;
|
|
|
|
this->m_triangulatedVertices = mesh.m_triangulatedVertices;
|
|
|
|
this->m_triangulatedFaces = mesh.m_triangulatedFaces;
|
|
|
|
}
|
|
|
|
|
|
|
|
MeshLoader::MeshLoader(Vertex *triangleVertices, int vertexNum) :
|
|
|
|
m_triangleVertices(triangleVertices),
|
|
|
|
m_triangleVertexCount(vertexNum),
|
|
|
|
m_edgeVertices(nullptr),
|
|
|
|
m_edgeVertexCount(0),
|
|
|
|
m_textureImage(nullptr)
|
|
|
|
{
|
2018-05-10 09:16:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
MeshLoader::MeshLoader(MeshResultContext &resultContext) :
|
|
|
|
m_triangleVertices(nullptr),
|
|
|
|
m_triangleVertexCount(0),
|
|
|
|
m_edgeVertices(nullptr),
|
|
|
|
m_edgeVertexCount(0),
|
|
|
|
m_textureImage(nullptr)
|
|
|
|
{
|
|
|
|
for (const auto &part: resultContext.parts()) {
|
|
|
|
m_triangleVertexCount += part.second.triangles.size() * 3;
|
|
|
|
}
|
|
|
|
m_triangleVertices = new Vertex[m_triangleVertexCount];
|
|
|
|
int destIndex = 0;
|
|
|
|
for (const auto &part: resultContext.parts()) {
|
|
|
|
for (const auto &it: part.second.triangles) {
|
|
|
|
for (auto i = 0; i < 3; i++) {
|
|
|
|
int vertexIndex = it.indicies[i];
|
|
|
|
const ResultVertex *srcVert = &part.second.vertices[vertexIndex];
|
|
|
|
const QVector3D *srcNormal = &part.second.interpolatedVertexNormals[vertexIndex];
|
|
|
|
const ResultVertexUv *srcUv = &part.second.vertexUvs[vertexIndex];
|
|
|
|
Vertex *dest = &m_triangleVertices[destIndex];
|
|
|
|
dest->colorR = 0;
|
|
|
|
dest->colorG = 0;
|
|
|
|
dest->colorB = 0;
|
|
|
|
dest->posX = srcVert->position.x();
|
|
|
|
dest->posY = srcVert->position.y();
|
|
|
|
dest->posZ = srcVert->position.z();
|
|
|
|
dest->texU = srcUv->uv[0];
|
|
|
|
dest->texV = srcUv->uv[1];
|
|
|
|
dest->normX = srcNormal->x();
|
|
|
|
dest->normY = srcNormal->y();
|
|
|
|
dest->normZ = srcNormal->z();
|
|
|
|
destIndex++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-07 17:16:58 +00:00
|
|
|
MeshLoader::~MeshLoader()
|
2018-03-10 06:57:14 +00:00
|
|
|
{
|
2018-03-19 13:56:10 +00:00
|
|
|
delete[] m_triangleVertices;
|
|
|
|
m_triangleVertexCount = 0;
|
2018-06-11 14:24:25 +00:00
|
|
|
delete[] m_edgeVertices;
|
|
|
|
m_edgeVertexCount = 0;
|
2018-05-10 09:16:22 +00:00
|
|
|
delete m_textureImage;
|
2018-03-10 06:57:14 +00:00
|
|
|
}
|
|
|
|
|
2018-05-07 17:16:58 +00:00
|
|
|
const std::vector<QVector3D> &MeshLoader::vertices()
|
2018-03-20 07:56:49 +00:00
|
|
|
{
|
|
|
|
return m_vertices;
|
|
|
|
}
|
|
|
|
|
2018-05-07 17:16:58 +00:00
|
|
|
const std::vector<std::vector<int>> &MeshLoader::faces()
|
2018-03-20 07:56:49 +00:00
|
|
|
{
|
|
|
|
return m_faces;
|
|
|
|
}
|
|
|
|
|
2018-05-07 17:16:58 +00:00
|
|
|
const std::vector<QVector3D> &MeshLoader::triangulatedVertices()
|
2018-04-26 02:23:22 +00:00
|
|
|
{
|
|
|
|
return m_triangulatedVertices;
|
|
|
|
}
|
|
|
|
|
2018-05-07 17:16:58 +00:00
|
|
|
const std::vector<TriangulatedFace> &MeshLoader::triangulatedFaces()
|
2018-04-26 02:23:22 +00:00
|
|
|
{
|
|
|
|
return m_triangulatedFaces;
|
|
|
|
}
|
|
|
|
|
2018-05-07 17:16:58 +00:00
|
|
|
Vertex *MeshLoader::triangleVertices()
|
2018-03-10 06:57:14 +00:00
|
|
|
{
|
2018-03-19 13:56:10 +00:00
|
|
|
return m_triangleVertices;
|
2018-03-10 06:57:14 +00:00
|
|
|
}
|
|
|
|
|
2018-05-07 17:16:58 +00:00
|
|
|
int MeshLoader::triangleVertexCount()
|
2018-03-10 06:57:14 +00:00
|
|
|
{
|
2018-03-19 13:56:10 +00:00
|
|
|
return m_triangleVertexCount;
|
2018-03-10 06:57:14 +00:00
|
|
|
}
|
2018-03-19 13:56:10 +00:00
|
|
|
|
2018-05-07 17:16:58 +00:00
|
|
|
Vertex *MeshLoader::edgeVertices()
|
2018-03-19 13:56:10 +00:00
|
|
|
{
|
|
|
|
return m_edgeVertices;
|
|
|
|
}
|
|
|
|
|
2018-05-07 17:16:58 +00:00
|
|
|
int MeshLoader::edgeVertexCount()
|
2018-03-19 13:56:10 +00:00
|
|
|
{
|
|
|
|
return m_edgeVertexCount;
|
|
|
|
}
|
|
|
|
|
2018-05-10 09:16:22 +00:00
|
|
|
void MeshLoader::setTextureImage(QImage *textureImage)
|
|
|
|
{
|
|
|
|
m_textureImage = textureImage;
|
|
|
|
}
|
2018-03-19 13:56:10 +00:00
|
|
|
|
2018-05-10 09:16:22 +00:00
|
|
|
const QImage *MeshLoader::textureImage()
|
|
|
|
{
|
|
|
|
return m_textureImage;
|
|
|
|
}
|