diff --git a/src/cutface.cpp b/src/cutface.cpp index a17a394a..e7d93118 100644 --- a/src/cutface.cpp +++ b/src/cutface.cpp @@ -72,7 +72,8 @@ void normalizeCutFacePoints(std::vector *points) correctFlippedNormal(points); } -void cutFacePointsFromNodes(std::vector &points, const std::vector> &nodes, bool isRing) +void cutFacePointsFromNodes(std::vector &points, const std::vector> &nodes, bool isRing, + std::vector *pointsIds) { if (isRing) { if (nodes.size() < 3) @@ -80,6 +81,11 @@ void cutFacePointsFromNodes(std::vector &points, const std::vector(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 &points, const std::vectorpush_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); } diff --git a/src/cutface.h b/src/cutface.h index 03854fbd..e87d2a0a 100644 --- a/src/cutface.h +++ b/src/cutface.h @@ -97,6 +97,7 @@ std::vector CutFaceToPoints(CutFace cutFace) \ } void normalizeCutFacePoints(std::vector *points); -void cutFacePointsFromNodes(std::vector &points, const std::vector> &nodes, bool isRing=false); +void cutFacePointsFromNodes(std::vector &points, const std::vector> &nodes, bool isRing=false, + std::vector *pointsIds=nullptr); #endif diff --git a/src/document.cpp b/src/document.cpp index 5e9eb8ec..612eccca 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -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; diff --git a/src/document.h b/src/document.h index 03d08ed0..3cdeffd8 100644 --- a/src/document.h +++ b/src/document.h @@ -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 *m_resultMeshCutFaceTransforms; + std::map> *m_resultMeshNodesCutFaces; bool m_isMeshGenerationSucceed; int m_batchChangeRefCount; Outcome *m_currentOutcome; diff --git a/src/meshgenerator.cpp b/src/meshgenerator.cpp index b360593f..9548da91 100644 --- a/src/meshgenerator.cpp +++ b/src/meshgenerator.cpp @@ -69,7 +69,7 @@ std::map *MeshGenerator::takeCutFace return cutFaceTransforms; } -std::map>> *MeshGenerator::takeNodesCutFaces() +std::map> *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> cutFaceNodeMap; + std::map cutTemplateMapByName; std::vector cutTemplate; QString cutFaceString = valueOfKeyInMapOrEmpty(part, "cutFace"); QUuid cutFaceLinkedPartId = QUuid(cutFaceString); if (!cutFaceLinkedPartId.isNull()) { + std::map> 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> cutFaceNodes; + std::vector> cutFaceNodes; std::set cutFaceVisitedNodeIds; std::function 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 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; - m_nodesCutFaces = new std::map>>; + m_nodesCutFaces = new std::map>; bool needDeleteCacheContext = false; if (nullptr == m_cacheContext) { diff --git a/src/meshgenerator.h b/src/meshgenerator.h index 7b25a892..89528f69 100644 --- a/src/meshgenerator.h +++ b/src/meshgenerator.h @@ -61,7 +61,7 @@ public: const std::set &generatedPreviewPartIds(); Outcome *takeOutcome(); std::map *takeCutFaceTransforms(); - std::map>> *takeNodesCutFaces(); + std::map> *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 *m_cutFaceTransforms = nullptr; - std::map>> *m_nodesCutFaces = nullptr; + std::map> *m_nodesCutFaces = nullptr; void collectParts(); bool checkIsComponentDirty(const QString &componentIdString); diff --git a/src/meshloader.cpp b/src/meshloader.cpp index d28561d6..8debbde5 100644 --- a/src/meshloader.cpp +++ b/src/meshloader.cpp @@ -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; +} diff --git a/src/meshloader.h b/src/meshloader.h index 2ab9fee5..3ef9a1a1 100644 --- a/src/meshloader.h +++ b/src/meshloader.h @@ -8,6 +8,7 @@ #include #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; diff --git a/src/modelmeshbinder.cpp b/src/modelmeshbinder.cpp index 44644da0..f8bbc2cb 100644 --- a/src/modelmeshbinder.cpp +++ b/src/modelmeshbinder.cpp @@ -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(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(3 * sizeof(GLfloat))); + f->glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast(6 * sizeof(GLfloat))); + f->glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast(9 * sizeof(GLfloat))); + f->glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast(11 * sizeof(GLfloat))); + f->glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast(12 * sizeof(GLfloat))); + f->glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast(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; diff --git a/src/modelmeshbinder.h b/src/modelmeshbinder.h index b0c58326..64cdc2f0 100644 --- a/src/modelmeshbinder.h +++ b/src/modelmeshbinder.h @@ -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; }; diff --git a/src/modelwidget.cpp b/src/modelwidget.cpp index 09d752ca..d6d431a9 100644 --- a/src/modelwidget.cpp +++ b/src/modelwidget.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "modelwidget.h" #include "util.h" diff --git a/src/modelwidget.h b/src/modelwidget.h index e37d345b..e5d2e970 100644 --- a/src/modelwidget.h +++ b/src/modelwidget.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "meshloader.h" #include "modelshaderprogram.h" #include "modelmeshbinder.h" diff --git a/src/toolmesh.cpp b/src/toolmesh.cpp index 14ae39b9..d9fe1a7a 100644 --- a/src/toolmesh.cpp +++ b/src/toolmesh.cpp @@ -1,17 +1,96 @@ #include "toolmesh.h" +#include "theme.h" -void ToolMesh::addNode(const QVector3D &position, float radius, const QMatrix4x4 &transform) +const std::vector 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 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 *vertices, const QVector3D &position) +{ + auto addTriangle = [&](const std::vector &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; } diff --git a/src/toolmesh.h b/src/toolmesh.h index 9e3851be..ecf150ff 100644 --- a/src/toolmesh.h +++ b/src/toolmesh.h @@ -3,12 +3,14 @@ #include #include #include +#include #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 m_nodes; - ShaderVertex *m_shaderVertices = nullptr; + std::map m_nodes; + std::map> m_nodesVertices; + + static const std::vector m_predefinedPoints; + static const std::vector m_predefinedNormals; + + void fillCube(std::vector *vertices, const QVector3D &position); }; #endif diff --git a/thirdparty/nodemesh/nodemesh/builder.cpp b/thirdparty/nodemesh/nodemesh/builder.cpp index ef03bd0e..d742b7ee 100644 --- a/thirdparty/nodemesh/nodemesh/builder.cpp +++ b/thirdparty/nodemesh/nodemesh/builder.cpp @@ -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; } diff --git a/thirdparty/nodemesh/nodemesh/builder.h b/thirdparty/nodemesh/nodemesh/builder.h index 746595d2..62cf1e11 100644 --- a/thirdparty/nodemesh/nodemesh/builder.h +++ b/thirdparty/nodemesh/nodemesh/builder.h @@ -15,6 +15,8 @@ class Builder public: struct CutFaceTransform { + QVector3D translation; + float scale; QMatrix4x4 rotation; QVector3D uFactor; QVector3D vFactor;