Prepare for cut face offset modifier
parent
820aa90406
commit
eb91a8a16c
|
@ -72,7 +72,8 @@ void normalizeCutFacePoints(std::vector<QVector2D> *points)
|
|||
correctFlippedNormal(points);
|
||||
}
|
||||
|
||||
void cutFacePointsFromNodes(std::vector<QVector2D> &points, const std::vector<std::tuple<float, float, float>> &nodes, bool isRing)
|
||||
void cutFacePointsFromNodes(std::vector<QVector2D> &points, const std::vector<std::tuple<float, float, float, QString>> &nodes, bool isRing,
|
||||
std::vector<QString> *pointsIds)
|
||||
{
|
||||
if (isRing) {
|
||||
if (nodes.size() < 3)
|
||||
|
@ -80,6 +81,11 @@ void cutFacePointsFromNodes(std::vector<QVector2D> &points, const std::vector<st
|
|||
for (const auto &it: nodes) {
|
||||
points.push_back(QVector2D(std::get<1>(it), std::get<2>(it)));
|
||||
}
|
||||
if (nullptr != pointsIds) {
|
||||
for (const auto &it: nodes) {
|
||||
pointsIds->push_back(std::get<3>(it));
|
||||
}
|
||||
}
|
||||
normalizeCutFacePoints(&points);
|
||||
return;
|
||||
}
|
||||
|
@ -117,8 +123,18 @@ void cutFacePointsFromNodes(std::vector<QVector2D> &points, const std::vector<st
|
|||
for (const auto &it: cutPoints) {
|
||||
points.push_back(it.first);
|
||||
}
|
||||
if (nullptr != pointsIds) {
|
||||
for (const auto &it: nodes) {
|
||||
pointsIds->push_back(std::get<3>(it) + QString("/1"));
|
||||
}
|
||||
}
|
||||
for (auto it = cutPoints.rbegin(); it != cutPoints.rend(); ++it) {
|
||||
points.push_back(it->second);
|
||||
}
|
||||
if (nullptr != pointsIds) {
|
||||
for (auto it = nodes.rbegin(); it != nodes.rend(); ++it) {
|
||||
pointsIds->push_back(std::get<3>(*it) + QString("/2"));
|
||||
}
|
||||
}
|
||||
normalizeCutFacePoints(&points);
|
||||
}
|
||||
|
|
|
@ -97,6 +97,7 @@ std::vector<QVector2D> CutFaceToPoints(CutFace cutFace) \
|
|||
}
|
||||
|
||||
void normalizeCutFacePoints(std::vector<QVector2D> *points);
|
||||
void cutFacePointsFromNodes(std::vector<QVector2D> &points, const std::vector<std::tuple<float, float, float>> &nodes, bool isRing=false);
|
||||
void cutFacePointsFromNodes(std::vector<QVector2D> &points, const std::vector<std::tuple<float, float, float, QString>> &nodes, bool isRing=false,
|
||||
std::vector<QString> *pointsIds=nullptr);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,6 +35,8 @@ Document::Document() :
|
|||
m_isResultMeshObsolete(false),
|
||||
m_meshGenerator(nullptr),
|
||||
m_resultMesh(nullptr),
|
||||
m_resultMeshCutFaceTransforms(nullptr),
|
||||
m_resultMeshNodesCutFaces(nullptr),
|
||||
m_isMeshGenerationSucceed(true),
|
||||
m_batchChangeRefCount(0),
|
||||
m_currentOutcome(nullptr),
|
||||
|
@ -80,6 +82,8 @@ void Document::applyPreferenceFlatShadingChange()
|
|||
Document::~Document()
|
||||
{
|
||||
delete m_resultMesh;
|
||||
delete m_resultMeshCutFaceTransforms;
|
||||
delete m_resultMeshNodesCutFaces;
|
||||
delete m_postProcessedOutcome;
|
||||
delete textureGuideImage;
|
||||
delete textureImage;
|
||||
|
@ -1516,6 +1520,14 @@ void Document::meshReady()
|
|||
delete m_resultMesh;
|
||||
m_resultMesh = resultMesh;
|
||||
|
||||
delete m_resultMeshCutFaceTransforms;
|
||||
m_resultMeshCutFaceTransforms = m_meshGenerator->takeCutFaceTransforms();
|
||||
|
||||
delete m_resultMeshNodesCutFaces;
|
||||
m_resultMeshNodesCutFaces = m_meshGenerator->takeNodesCutFaces();
|
||||
|
||||
//addToolToMesh(m_resultMesh);
|
||||
|
||||
m_isMeshGenerationSucceed = isSucceed;
|
||||
|
||||
delete m_currentOutcome;
|
||||
|
@ -1540,6 +1552,36 @@ void Document::meshReady()
|
|||
}
|
||||
}
|
||||
|
||||
//void Document::addToolToMesh(MeshLoader *mesh)
|
||||
//{
|
||||
// if (nullptr == mesh)
|
||||
// return;
|
||||
//
|
||||
// if (nullptr == m_resultMeshCutFaceTransforms ||
|
||||
// nullptr == m_resultMeshNodesCutFaces ||
|
||||
// m_resultMeshCutFaceTransforms->empty() ||
|
||||
// m_resultMeshNodesCutFaces->empty())
|
||||
// return;
|
||||
//
|
||||
// ToolMesh toolMesh;
|
||||
// for (const auto &transformIt: *m_resultMeshCutFaceTransforms) {
|
||||
// const auto &nodeId = transformIt.first;
|
||||
// const auto &transform = transformIt.second;
|
||||
// qDebug() << "nodeId:" << nodeId;
|
||||
// for (const auto &cutFaceIt: (*m_resultMeshNodesCutFaces)[nodeId]) {
|
||||
// const auto &cutFaceId = cutFaceIt.first;
|
||||
// const auto &cutFace2d = cutFaceIt.second;
|
||||
// QVector3D position = transform.translation + transform.rotation * (transform.uFactor * cutFace2d.x() + transform.vFactor * cutFace2d.y());
|
||||
// qDebug() << "cutFaceId:" << cutFaceId;
|
||||
// toolMesh.addNode(nodeId.toString() + cutFaceId, position);
|
||||
// }
|
||||
// }
|
||||
// toolMesh.generate();
|
||||
// int shaderVertexCount = 0;
|
||||
// ShaderVertex *shaderVertices = toolMesh.takeShaderVertices(&shaderVertexCount);
|
||||
// mesh->updateTool(shaderVertices, shaderVertexCount);
|
||||
//}
|
||||
|
||||
bool Document::isPostProcessResultObsolete() const
|
||||
{
|
||||
return m_isPostProcessResultObsolete;
|
||||
|
@ -1668,6 +1710,8 @@ void Document::textureReady()
|
|||
delete m_resultTextureMesh;
|
||||
m_resultTextureMesh = m_textureGenerator->takeResultMesh();
|
||||
|
||||
//addToolToMesh(m_resultTextureMesh);
|
||||
|
||||
m_textureImageUpdateVersion++;
|
||||
|
||||
delete m_textureGenerator;
|
||||
|
|
|
@ -651,10 +651,13 @@ private:
|
|||
void markAllDirty();
|
||||
void removeRigResults();
|
||||
void updateLinkedPart(QUuid oldPartId, QUuid newPartId);
|
||||
//void addToolToMesh(MeshLoader *mesh);
|
||||
private: // need initialize
|
||||
bool m_isResultMeshObsolete;
|
||||
MeshGenerator *m_meshGenerator;
|
||||
MeshLoader *m_resultMesh;
|
||||
std::map<QUuid, nodemesh::Builder::CutFaceTransform> *m_resultMeshCutFaceTransforms;
|
||||
std::map<QUuid, std::map<QString, QVector2D>> *m_resultMeshNodesCutFaces;
|
||||
bool m_isMeshGenerationSucceed;
|
||||
int m_batchChangeRefCount;
|
||||
Outcome *m_currentOutcome;
|
||||
|
|
|
@ -69,7 +69,7 @@ std::map<QUuid, nodemesh::Builder::CutFaceTransform> *MeshGenerator::takeCutFace
|
|||
return cutFaceTransforms;
|
||||
}
|
||||
|
||||
std::map<QUuid, std::map<QString, std::tuple<float, float, float>>> *MeshGenerator::takeNodesCutFaces()
|
||||
std::map<QUuid, std::map<QString, QVector2D>> *MeshGenerator::takeNodesCutFaces()
|
||||
{
|
||||
auto nodesCutFaces = m_nodesCutFaces;
|
||||
m_nodesCutFaces = nullptr;
|
||||
|
@ -190,11 +190,12 @@ nodemesh::Combiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdSt
|
|||
auto target = PartTargetFromString(valueOfKeyInMapOrEmpty(part, "target").toUtf8().constData());
|
||||
auto base = PartBaseFromString(valueOfKeyInMapOrEmpty(part, "base").toUtf8().constData());
|
||||
|
||||
std::map<QString, std::tuple<float, float, float>> cutFaceNodeMap;
|
||||
std::map<QString, QVector2D> cutTemplateMapByName;
|
||||
std::vector<QVector2D> cutTemplate;
|
||||
QString cutFaceString = valueOfKeyInMapOrEmpty(part, "cutFace");
|
||||
QUuid cutFaceLinkedPartId = QUuid(cutFaceString);
|
||||
if (!cutFaceLinkedPartId.isNull()) {
|
||||
std::map<QString, std::tuple<float, float, float>> cutFaceNodeMap;
|
||||
auto findCutFaceLinkedPart = m_snapshot->parts.find(cutFaceString);
|
||||
if (findCutFaceLinkedPart == m_snapshot->parts.end()) {
|
||||
qDebug() << "Find cut face linked part failed:" << cutFaceString;
|
||||
|
@ -275,7 +276,7 @@ nodemesh::Combiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdSt
|
|||
endPointNodeIdString = endpointNodes[0].first;
|
||||
}
|
||||
// Loop all linked nodes
|
||||
std::vector<std::tuple<float, float, float>> cutFaceNodes;
|
||||
std::vector<std::tuple<float, float, float, QString>> cutFaceNodes;
|
||||
std::set<QString> cutFaceVisitedNodeIds;
|
||||
std::function<void (const QString &)> loopNodeLink;
|
||||
loopNodeLink = [&](const QString &fromNodeIdString) {
|
||||
|
@ -285,7 +286,10 @@ nodemesh::Combiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdSt
|
|||
if (cutFaceVisitedNodeIds.find(fromNodeIdString) != cutFaceVisitedNodeIds.end())
|
||||
return;
|
||||
cutFaceVisitedNodeIds.insert(fromNodeIdString);
|
||||
cutFaceNodes.push_back(findCutFaceNode->second);
|
||||
cutFaceNodes.push_back({std::get<0>(findCutFaceNode->second),
|
||||
std::get<1>(findCutFaceNode->second),
|
||||
std::get<2>(findCutFaceNode->second),
|
||||
fromNodeIdString});
|
||||
auto findNeighbor = cutFaceNodeLinkMap.find(fromNodeIdString);
|
||||
if (findNeighbor == cutFaceNodeLinkMap.end())
|
||||
return;
|
||||
|
@ -300,12 +304,20 @@ nodemesh::Combiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdSt
|
|||
loopNodeLink(endPointNodeIdString);
|
||||
}
|
||||
// Fetch points from linked nodes
|
||||
cutFacePointsFromNodes(cutTemplate, cutFaceNodes, isRing);
|
||||
std::vector<QString> cutTemplateNames;
|
||||
cutFacePointsFromNodes(cutTemplate, cutFaceNodes, isRing, &cutTemplateNames);
|
||||
for (size_t i = 0; i < cutTemplateNames.size(); ++i) {
|
||||
cutTemplateMapByName.insert({cutTemplateNames[i], cutTemplate[i]});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cutTemplate.size() < 3) {
|
||||
CutFace cutFace = CutFaceFromString(cutFaceString.toUtf8().constData());
|
||||
cutTemplate = CutFaceToPoints(cutFace);
|
||||
cutTemplateMapByName.clear();
|
||||
for (size_t i = 0; i < cutTemplate.size(); ++i) {
|
||||
cutTemplateMapByName.insert({cutFaceString + "/" + QString::number(i + 1), cutTemplate[i]});
|
||||
}
|
||||
}
|
||||
if (chamfered)
|
||||
nodemesh::chamferFace2D(&cutTemplate);
|
||||
|
@ -494,10 +506,11 @@ nodemesh::Combiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdSt
|
|||
continue;
|
||||
const QString &nodeIdString = nodeIndexToIdStringMap[node.originNodeIndex];
|
||||
const nodemesh::Builder::CutFaceTransform *cutFaceTransform = builder->nodeAdjustableCutFaceTransform(builderNodeIndices[i]);
|
||||
if (nullptr != cutFaceTransform) {
|
||||
if (nullptr != cutFaceTransform &&
|
||||
PartTarget::Model == target) {
|
||||
QUuid nodeId = QUuid(nodeIdString);
|
||||
m_cutFaceTransforms->insert({nodeId, *cutFaceTransform});
|
||||
m_nodesCutFaces->insert({nodeId, cutFaceNodeMap});
|
||||
m_nodesCutFaces->insert({nodeId, cutTemplateMapByName});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -993,7 +1006,7 @@ void MeshGenerator::generate()
|
|||
|
||||
m_outcome = new Outcome;
|
||||
m_cutFaceTransforms = new std::map<QUuid, nodemesh::Builder::CutFaceTransform>;
|
||||
m_nodesCutFaces = new std::map<QUuid, std::map<QString, std::tuple<float, float, float>>>;
|
||||
m_nodesCutFaces = new std::map<QUuid, std::map<QString, QVector2D>>;
|
||||
|
||||
bool needDeleteCacheContext = false;
|
||||
if (nullptr == m_cacheContext) {
|
||||
|
|
|
@ -61,7 +61,7 @@ public:
|
|||
const std::set<QUuid> &generatedPreviewPartIds();
|
||||
Outcome *takeOutcome();
|
||||
std::map<QUuid, nodemesh::Builder::CutFaceTransform> *takeCutFaceTransforms();
|
||||
std::map<QUuid, std::map<QString, std::tuple<float, float, float>>> *takeNodesCutFaces();
|
||||
std::map<QUuid, std::map<QString, QVector2D>> *takeNodesCutFaces();
|
||||
void generate();
|
||||
void setGeneratedCacheContext(GeneratedCacheContext *cacheContext);
|
||||
void setSmoothShadingThresholdAngleDegrees(float degrees);
|
||||
|
@ -90,7 +90,7 @@ private:
|
|||
bool m_cacheEnabled = false;
|
||||
float m_smoothShadingThresholdAngleDegrees = 60;
|
||||
std::map<QUuid, nodemesh::Builder::CutFaceTransform> *m_cutFaceTransforms = nullptr;
|
||||
std::map<QUuid, std::map<QString, std::tuple<float, float, float>>> *m_nodesCutFaces = nullptr;
|
||||
std::map<QUuid, std::map<QString, QVector2D>> *m_nodesCutFaces = nullptr;
|
||||
|
||||
void collectParts();
|
||||
bool checkIsComponentDirty(const QString &componentIdString);
|
||||
|
|
|
@ -31,6 +31,13 @@ MeshLoader::MeshLoader(const MeshLoader &mesh) :
|
|||
for (int i = 0; i < mesh.m_edgeVertexCount; i++)
|
||||
this->m_edgeVertices[i] = mesh.m_edgeVertices[i];
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
@ -332,3 +339,13 @@ void MeshLoader::exportAsObj(const QString &filename)
|
|||
exportAsObj(&stream);
|
||||
}
|
||||
}
|
||||
|
||||
void MeshLoader::updateTool(ShaderVertex *toolVertices, int vertexNum)
|
||||
{
|
||||
delete[] m_toolVertices;
|
||||
m_toolVertices = nullptr;
|
||||
m_toolVertexCount = 0;
|
||||
|
||||
m_toolVertices = toolVertices;
|
||||
m_toolVertexCount = vertexNum;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <QTextStream>
|
||||
#include "outcome.h"
|
||||
#include "shadervertex.h"
|
||||
#include "toolmesh.h"
|
||||
|
||||
struct TriangulatedFace
|
||||
{
|
||||
|
@ -52,6 +53,7 @@ public:
|
|||
static float m_defaultRoughness;
|
||||
void exportAsObj(const QString &filename);
|
||||
void exportAsObj(QTextStream *textStream);
|
||||
void updateTool(ShaderVertex *toolVertices, int vertexNum);
|
||||
private:
|
||||
ShaderVertex *m_triangleVertices = nullptr;
|
||||
int m_triangleVertexCount = 0;
|
||||
|
|
|
@ -8,21 +8,8 @@
|
|||
#include "modelmeshbinder.h"
|
||||
#include "ds3file.h"
|
||||
|
||||
ModelMeshBinder::ModelMeshBinder() :
|
||||
m_mesh(nullptr),
|
||||
m_newMesh(nullptr),
|
||||
m_renderTriangleVertexCount(0),
|
||||
m_renderEdgeVertexCount(0),
|
||||
m_newMeshComing(false),
|
||||
m_showWireframes(false),
|
||||
m_hasTexture(false),
|
||||
m_texture(nullptr),
|
||||
m_hasNormalMap(false),
|
||||
m_normalMap(nullptr),
|
||||
m_hasMetalnessMap(false),
|
||||
m_hasRoughnessMap(false),
|
||||
m_hasAmbientOcclusionMap(false),
|
||||
m_metalnessRoughnessAmbientOcclusionMap(nullptr)
|
||||
ModelMeshBinder::ModelMeshBinder(bool toolEnabled) :
|
||||
m_toolEnabled(toolEnabled)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -49,6 +36,8 @@ void ModelMeshBinder::initialize()
|
|||
{
|
||||
m_vaoTriangle.create();
|
||||
m_vaoEdge.create();
|
||||
if (m_toolEnabled)
|
||||
m_vaoTool.create();
|
||||
}
|
||||
|
||||
void ModelMeshBinder::paint(ModelShaderProgram *program)
|
||||
|
@ -142,9 +131,37 @@ void ModelMeshBinder::paint(ModelShaderProgram *program)
|
|||
f->glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(13 * sizeof(GLfloat)));
|
||||
m_vboEdge.release();
|
||||
}
|
||||
if (m_toolEnabled) {
|
||||
QOpenGLVertexArrayObject::Binder vaoBinder(&m_vaoTool);
|
||||
if (m_vboTool.isCreated())
|
||||
m_vboTool.destroy();
|
||||
m_vboTool.create();
|
||||
m_vboTool.bind();
|
||||
m_vboTool.allocate(m_mesh->toolVertices(), m_mesh->toolVertexCount() * sizeof(ShaderVertex));
|
||||
m_renderToolVertexCount = m_mesh->toolVertexCount();
|
||||
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
|
||||
f->glEnableVertexAttribArray(0);
|
||||
f->glEnableVertexAttribArray(1);
|
||||
f->glEnableVertexAttribArray(2);
|
||||
f->glEnableVertexAttribArray(3);
|
||||
f->glEnableVertexAttribArray(4);
|
||||
f->glEnableVertexAttribArray(5);
|
||||
f->glEnableVertexAttribArray(6);
|
||||
f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), 0);
|
||||
f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(3 * sizeof(GLfloat)));
|
||||
f->glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(6 * sizeof(GLfloat)));
|
||||
f->glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(9 * sizeof(GLfloat)));
|
||||
f->glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(11 * sizeof(GLfloat)));
|
||||
f->glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(12 * sizeof(GLfloat)));
|
||||
f->glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(13 * sizeof(GLfloat)));
|
||||
m_vboTool.release();
|
||||
} else {
|
||||
m_renderToolVertexCount = 0;
|
||||
}
|
||||
} else {
|
||||
m_renderTriangleVertexCount = 0;
|
||||
m_renderEdgeVertexCount = 0;
|
||||
m_renderToolVertexCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -190,6 +207,18 @@ void ModelMeshBinder::paint(ModelShaderProgram *program)
|
|||
program->setUniformValue(program->ambientOcclusionMapEnabledLoc(), m_hasAmbientOcclusionMap ? 1 : 0);
|
||||
f->glDrawArrays(GL_TRIANGLES, 0, m_renderTriangleVertexCount);
|
||||
}
|
||||
if (m_toolEnabled) {
|
||||
if (m_renderToolVertexCount > 0) {
|
||||
QOpenGLVertexArrayObject::Binder vaoBinder(&m_vaoTool);
|
||||
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
|
||||
program->setUniformValue(program->textureEnabledLoc(), 0);
|
||||
program->setUniformValue(program->normalMapEnabledLoc(), 0);
|
||||
program->setUniformValue(program->metalnessMapEnabledLoc(), 0);
|
||||
program->setUniformValue(program->roughnessMapEnabledLoc(), 0);
|
||||
program->setUniformValue(program->ambientOcclusionMapEnabledLoc(), 0);
|
||||
f->glDrawArrays(GL_TRIANGLES, 0, m_renderToolVertexCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ModelMeshBinder::cleanup()
|
||||
|
@ -198,6 +227,10 @@ void ModelMeshBinder::cleanup()
|
|||
m_vboTriangle.destroy();
|
||||
if (m_vboEdge.isCreated())
|
||||
m_vboEdge.destroy();
|
||||
if (m_toolEnabled) {
|
||||
if (m_vboTool.isCreated())
|
||||
m_vboTool.destroy();
|
||||
}
|
||||
delete m_texture;
|
||||
m_texture = nullptr;
|
||||
delete m_normalMap;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
class ModelMeshBinder
|
||||
{
|
||||
public:
|
||||
ModelMeshBinder();
|
||||
ModelMeshBinder(bool toolEnabled=false);
|
||||
~ModelMeshBinder();
|
||||
void updateMesh(MeshLoader *mesh);
|
||||
void initialize();
|
||||
|
@ -21,25 +21,29 @@ public:
|
|||
void hideWireframes();
|
||||
bool isWireframesVisible();
|
||||
private:
|
||||
MeshLoader *m_mesh;
|
||||
MeshLoader *m_newMesh;
|
||||
int m_renderTriangleVertexCount;
|
||||
int m_renderEdgeVertexCount;
|
||||
bool m_newMeshComing;
|
||||
bool m_showWireframes;
|
||||
bool m_hasTexture;
|
||||
QOpenGLTexture *m_texture;
|
||||
bool m_hasNormalMap;
|
||||
QOpenGLTexture *m_normalMap;
|
||||
bool m_hasMetalnessMap;
|
||||
bool m_hasRoughnessMap;
|
||||
bool m_hasAmbientOcclusionMap;
|
||||
QOpenGLTexture *m_metalnessRoughnessAmbientOcclusionMap;
|
||||
MeshLoader *m_mesh = nullptr;
|
||||
MeshLoader *m_newMesh = nullptr;
|
||||
int m_renderTriangleVertexCount = 0;
|
||||
int m_renderEdgeVertexCount = 0;
|
||||
int m_renderToolVertexCount = 0;
|
||||
bool m_newMeshComing = false;
|
||||
bool m_showWireframes = false;
|
||||
bool m_hasTexture = false;
|
||||
QOpenGLTexture *m_texture = nullptr;
|
||||
bool m_hasNormalMap = false;
|
||||
QOpenGLTexture *m_normalMap = nullptr;
|
||||
bool m_hasMetalnessMap = false;
|
||||
bool m_hasRoughnessMap = false;
|
||||
bool m_hasAmbientOcclusionMap = false;
|
||||
QOpenGLTexture *m_metalnessRoughnessAmbientOcclusionMap = nullptr;
|
||||
bool m_toolEnabled = false;
|
||||
private:
|
||||
QOpenGLVertexArrayObject m_vaoTriangle;
|
||||
QOpenGLBuffer m_vboTriangle;
|
||||
QOpenGLVertexArrayObject m_vaoEdge;
|
||||
QOpenGLBuffer m_vboEdge;
|
||||
QOpenGLVertexArrayObject m_vaoTool;
|
||||
QOpenGLBuffer m_vboTool;
|
||||
QMutex m_meshMutex;
|
||||
QMutex m_newMeshMutex;
|
||||
};
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <QCoreApplication>
|
||||
#include <QGuiApplication>
|
||||
#include <math.h>
|
||||
#include <QVector4D>
|
||||
#include "modelwidget.h"
|
||||
#include "util.h"
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <QMatrix4x4>
|
||||
#include <QMutex>
|
||||
#include <QRubberBand>
|
||||
#include <QVector2D>
|
||||
#include "meshloader.h"
|
||||
#include "modelshaderprogram.h"
|
||||
#include "modelmeshbinder.h"
|
||||
|
|
|
@ -1,17 +1,96 @@
|
|||
#include "toolmesh.h"
|
||||
#include "theme.h"
|
||||
|
||||
void ToolMesh::addNode(const QVector3D &position, float radius, const QMatrix4x4 &transform)
|
||||
const std::vector<QVector3D> ToolMesh::m_predefinedPoints = {
|
||||
QVector3D(1.000000, 1.000000, -1.000000),
|
||||
QVector3D(1.000000, -1.000000, -1.000000),
|
||||
QVector3D(1.000000, 1.000000, 1.000000),
|
||||
QVector3D(1.000000, -1.000000, 1.000000),
|
||||
QVector3D(-1.000000, 1.000000, -1.000000),
|
||||
QVector3D(-1.000000, -1.000000, -1.000000),
|
||||
QVector3D(-1.000000, 1.000000, 1.000000),
|
||||
QVector3D(-1.000000, -1.000000, 1.000000),
|
||||
};
|
||||
|
||||
const std::vector<QVector3D> ToolMesh::m_predefinedNormals = {
|
||||
QVector3D(0.0000, 1.0000, 0.0000),
|
||||
QVector3D(0.0000, 0.0000, 1.0000),
|
||||
QVector3D(-1.0000, 0.0000, 0.0000),
|
||||
QVector3D(0.0000, -1.0000, 0.0000),
|
||||
QVector3D(1.0000, 0.0000, 0.0000),
|
||||
QVector3D(0.0000, 0.0000, -1.0000),
|
||||
};
|
||||
|
||||
ToolMesh::~ToolMesh()
|
||||
{
|
||||
m_nodes.push_back({position, radius, transform});
|
||||
}
|
||||
|
||||
void ToolMesh::addNode(const QString &nodeId, const QVector3D &position)
|
||||
{
|
||||
m_nodes.insert({nodeId, {position}});
|
||||
}
|
||||
|
||||
void ToolMesh::fillCube(std::vector<ShaderVertex> *vertices, const QVector3D &position)
|
||||
{
|
||||
auto addTriangle = [&](const std::vector<size_t> &indices, int normalIndex) {
|
||||
for (const auto &index: indices) {
|
||||
ShaderVertex vertex;
|
||||
memset(&vertex, 0, sizeof(ShaderVertex));
|
||||
|
||||
const auto &transformedPosition = position + m_predefinedPoints[index - 1] * 0.003;
|
||||
const auto &transformedNormal = m_predefinedNormals[normalIndex - 1];
|
||||
|
||||
vertex.posX = transformedPosition.x();
|
||||
vertex.posY = transformedPosition.y();
|
||||
vertex.posZ = transformedPosition.z();
|
||||
|
||||
vertex.normX = transformedNormal.x();
|
||||
vertex.normY = transformedNormal.y();
|
||||
vertex.normZ = transformedNormal.z();
|
||||
|
||||
vertex.colorR = Theme::green.redF();
|
||||
vertex.colorG = Theme::green.greenF();
|
||||
vertex.colorB = Theme::green.blueF();
|
||||
|
||||
vertices->push_back(vertex);
|
||||
}
|
||||
};
|
||||
|
||||
addTriangle({5, 3, 1}, 1);
|
||||
addTriangle({3, 8, 4}, 2);
|
||||
addTriangle({7, 6, 8}, 3);
|
||||
addTriangle({2, 8, 6}, 4);
|
||||
addTriangle({1, 4, 2}, 5);
|
||||
addTriangle({5, 2, 6}, 6);
|
||||
addTriangle({5, 7, 3}, 1);
|
||||
addTriangle({3, 7, 8}, 2);
|
||||
addTriangle({7, 5, 6}, 3);
|
||||
addTriangle({2, 4, 8}, 4);
|
||||
addTriangle({1, 3, 4}, 5);
|
||||
addTriangle({5, 1, 2}, 6);
|
||||
}
|
||||
|
||||
void ToolMesh::generate()
|
||||
{
|
||||
// TODO:
|
||||
for (const auto &node: m_nodes) {
|
||||
fillCube(&m_nodesVertices[node.first], node.second.position);
|
||||
}
|
||||
}
|
||||
|
||||
ShaderVertex *ToolMesh::takeShaderVertices(int *shaderVertexCount)
|
||||
{
|
||||
// TODO:
|
||||
return nullptr;
|
||||
int vertexCount = m_nodesVertices.size() * 12 * 3;
|
||||
ShaderVertex *shaderVertices = new ShaderVertex[vertexCount];
|
||||
if (nullptr != shaderVertexCount)
|
||||
*shaderVertexCount = vertexCount;
|
||||
int vertexIndex = 0;
|
||||
for (const auto &nodeIt: m_nodesVertices) {
|
||||
for (const auto &vertexIt: nodeIt.second) {
|
||||
Q_ASSERT(vertexIndex < vertexCount);
|
||||
ShaderVertex *dest = &shaderVertices[vertexIndex++];
|
||||
*dest = vertexIt;
|
||||
}
|
||||
}
|
||||
Q_ASSERT(vertexIndex == vertexCount);
|
||||
return shaderVertices;
|
||||
}
|
||||
|
|
|
@ -3,12 +3,14 @@
|
|||
#include <QVector3D>
|
||||
#include <QMatrix4x4>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "shadervertex.h"
|
||||
|
||||
class ToolMesh
|
||||
{
|
||||
public:
|
||||
void addNode(const QVector3D &position, float radius, const QMatrix4x4 &transform);
|
||||
~ToolMesh();
|
||||
void addNode(const QString &nodeId, const QVector3D &position);
|
||||
void generate();
|
||||
ShaderVertex *takeShaderVertices(int *shaderVertexCount);
|
||||
|
||||
|
@ -16,12 +18,15 @@ private:
|
|||
struct Node
|
||||
{
|
||||
QVector3D position;
|
||||
float radius;
|
||||
QMatrix4x4 transform;
|
||||
};
|
||||
|
||||
std::vector<Node> m_nodes;
|
||||
ShaderVertex *m_shaderVertices = nullptr;
|
||||
std::map<QString, Node> m_nodes;
|
||||
std::map<QString, std::vector<ShaderVertex>> m_nodesVertices;
|
||||
|
||||
static const std::vector<QVector3D> m_predefinedPoints;
|
||||
static const std::vector<QVector3D> m_predefinedNormals;
|
||||
|
||||
void fillCube(std::vector<ShaderVertex> *vertices, const QVector3D &position);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -711,6 +711,8 @@ void Builder::makeCut(const QVector3D &position,
|
|||
auto uFactor = u * radius;
|
||||
auto vFactor = v * radius;
|
||||
if (nullptr != cutFaceTransform) {
|
||||
cutFaceTransform->scale = radius;
|
||||
cutFaceTransform->translation = position;
|
||||
cutFaceTransform->uFactor = uFactor;
|
||||
cutFaceTransform->vFactor = vFactor;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@ class Builder
|
|||
public:
|
||||
struct CutFaceTransform
|
||||
{
|
||||
QVector3D translation;
|
||||
float scale;
|
||||
QMatrix4x4 rotation;
|
||||
QVector3D uFactor;
|
||||
QVector3D vFactor;
|
||||
|
|
Loading…
Reference in New Issue