diff --git a/src/meshgenerator.cpp b/src/meshgenerator.cpp index 1ecf9655..03f6821d 100644 --- a/src/meshgenerator.cpp +++ b/src/meshgenerator.cpp @@ -1105,9 +1105,6 @@ MeshCombiner::Mesh *MeshGenerator::combineComponentMesh(const QString &component m_clothCollisionVertices.clear(); m_clothCollisionTriangles.clear(); mesh->fetch(m_clothCollisionVertices, m_clothCollisionTriangles); - buildClothTargetNodes(componentCache.outcomeNodes, - componentCache.outcomeEdges, - &m_clothTargetNodes); } else { // TODO: when no body is valid, may add ground plane as collision shape // ... ... @@ -1124,7 +1121,12 @@ MeshCombiner::Mesh *MeshGenerator::combineComponentMesh(const QString &component std::vector newVertices; std::vector> newQuads; std::vector> newTriangles; + std::vector> interpolatedNodes; + buildInterpolatedNodes(componentCache.outcomeNodes, + componentCache.outcomeEdges, + &interpolatedNodes); remesh(componentCache.outcomeNodes, + interpolatedNodes, combinedVertices, combinedFaces, polyCountValue, @@ -1167,16 +1169,16 @@ MeshCombiner::Mesh *MeshGenerator::combineComponentMesh(const QString &component return mesh; } -void MeshGenerator::buildClothTargetNodes(const std::vector &nodes, +void MeshGenerator::buildInterpolatedNodes(const std::vector &nodes, const std::vector, std::pair>> &edges, - std::vector> *targetNodes) + std::vector> *targetNodes) { targetNodes->clear(); std::map, size_t> nodeMap; for (size_t nodeIndex = 0; nodeIndex < nodes.size(); ++nodeIndex) { const auto &it = nodes[nodeIndex]; nodeMap.insert({{it.partId, it.nodeId}, nodeIndex}); - targetNodes->push_back(std::make_pair(it.origin, it.radius * 3.0f)); + targetNodes->push_back(std::make_tuple(it.origin, it.radius, nodeIndex)); } for (const auto &it: edges) { auto findFirst = nodeMap.find(it.first); @@ -1197,9 +1199,10 @@ void MeshGenerator::buildClothTargetNodes(const std::vector &nodes, float offset = segmentLength; while (offset < 1.0f) { float radius = firstNode.radius * (1.0f - offset) + secondNode.radius * offset; - targetNodes->push_back(std::make_pair( + targetNodes->push_back(std::make_tuple( firstNode.origin * (1.0f - offset) + secondNode.origin * offset, - radius * 3.0 + radius * 3.0, + offset <= 0.5 ? findFirst->second : findSecond->second )); offset += segmentLength; } @@ -1587,6 +1590,7 @@ void MeshGenerator::generate() } void MeshGenerator::remesh(const std::vector &inputNodes, + const std::vector> &interpolatedNodes, const std::vector &inputVertices, const std::vector> &inputFaces, float targetVertexMultiplyFactor, @@ -1597,11 +1601,12 @@ void MeshGenerator::remesh(const std::vector &inputNodes, { std::vector> nodes; std::vector> sourceIds; - nodes.reserve(inputNodes.size()); - sourceIds.reserve(inputNodes.size()); - for (const auto &it: inputNodes) { - nodes.push_back(std::make_pair(it.origin, it.radius)); - sourceIds.push_back(std::make_pair(it.partId, it.nodeId)); + nodes.reserve(interpolatedNodes.size()); + sourceIds.reserve(interpolatedNodes.size()); + for (const auto &it: interpolatedNodes) { + nodes.push_back(std::make_pair(std::get<0>(it), std::get<1>(it))); + const auto &sourceNode = inputNodes[std::get<2>(it)]; + sourceIds.push_back(std::make_pair(sourceNode.partId, sourceNode.nodeId)); } Remesher remesher; remesher.setMesh(inputVertices, inputFaces); @@ -1699,7 +1704,7 @@ void MeshGenerator::collectClothComponentIdStrings(const QString &componentIdStr void MeshGenerator::collectClothComponent(const QString &componentIdString) { - if (m_clothCollisionTriangles.empty() || m_clothTargetNodes.empty()) + if (m_clothCollisionTriangles.empty()) return; std::vector componentIdStrings; @@ -1723,8 +1728,7 @@ void MeshGenerator::collectClothComponent(const QString &componentIdString) } simulateClothMeshes(&clothMeshes, &m_clothCollisionVertices, - &m_clothCollisionTriangles, - &m_clothTargetNodes); + &m_clothCollisionTriangles); for (auto &clothMesh: clothMeshes) { auto vertexStartIndex = m_outcome->vertices.size(); auto updateVertexIndices = [=](std::vector> &faces) { diff --git a/src/meshgenerator.h b/src/meshgenerator.h index 15a20e91..0e0bc9b8 100644 --- a/src/meshgenerator.h +++ b/src/meshgenerator.h @@ -106,7 +106,6 @@ private: quint64 m_id = 0; std::vector m_clothCollisionVertices; std::vector> m_clothCollisionTriangles; - std::vector> m_clothTargetNodes; void collectParts(); bool checkIsComponentDirty(const QString &componentIdString); @@ -142,6 +141,7 @@ private: std::vector *componentIdStrings); void cutFaceStringToCutTemplate(const QString &cutFaceString, std::vector &cutTemplate); void remesh(const std::vector &inputNodes, + const std::vector> &interpolatedNodes, const std::vector &inputVertices, const std::vector> &inputFaces, float targetVertexMultiplyFactor, @@ -149,9 +149,9 @@ private: std::vector> *outputQuads, std::vector> *outputTriangles, std::vector>> *outputNodeVertices); - void buildClothTargetNodes(const std::vector &nodes, + void buildInterpolatedNodes(const std::vector &nodes, const std::vector, std::pair>> &edges, - std::vector> *targetNodes); + std::vector> *targetNodes); }; #endif diff --git a/src/parttreewidget.cpp b/src/parttreewidget.cpp index 8ed80acb..85ffa8ba 100644 --- a/src/parttreewidget.cpp +++ b/src/parttreewidget.cpp @@ -383,7 +383,7 @@ void PartTreeWidget::showContextMenu(const QPoint &pos, bool shorted) std::vector componentIds = collectSelectedComponentIds(pos); if (shorted) { - if (componentIds.size() != 1) + if (componentIds.size() > 1) return; } diff --git a/src/projectfacestonodes.cpp b/src/projectfacestonodes.cpp index fdc9237a..15b1c725 100644 --- a/src/projectfacestonodes.cpp +++ b/src/projectfacestonodes.cpp @@ -69,7 +69,7 @@ void projectFacesToNodes(const std::vector &vertices, const std::vector> &sourceNodes, std::vector *faceSources) { - faceSources->resize(faces.size()); + faceSources->resize(faces.size(), std::numeric_limits::max()); tbb::parallel_for(tbb::blocked_range(0, faces.size()), FacesToNodesProjector(&vertices, &faces, &sourceNodes, faceSources)); } diff --git a/src/remesher.cpp b/src/remesher.cpp index 00d40d62..f5670d18 100644 --- a/src/remesher.cpp +++ b/src/remesher.cpp @@ -116,6 +116,8 @@ void Remesher::resolveSources() for (size_t i = 0; i < m_remeshedFaces.size(); ++i) { const auto &face = m_remeshedFaces[i]; const auto &source = faceSources[i]; + if (source >= m_nodes.size()) + continue; for (const auto &vertexIndex: face) vertexToNodeVotes[vertexIndex][source]++; } diff --git a/src/simulateclothmeshes.cpp b/src/simulateclothmeshes.cpp index 5e85eb3a..09a3835b 100644 --- a/src/simulateclothmeshes.cpp +++ b/src/simulateclothmeshes.cpp @@ -10,12 +10,10 @@ class ClothMeshesSimulator public: ClothMeshesSimulator(std::vector *clothMeshes, const std::vector *clothCollisionVertices, - const std::vector> *clothCollisionTriangles, - const std::vector> *clothTargetNodes) : + const std::vector> *clothCollisionTriangles) : m_clothMeshes(clothMeshes), m_clothCollisionVertices(clothCollisionVertices), - m_clothCollisionTriangles(clothCollisionTriangles), - m_clothTargetNodes(clothTargetNodes) + m_clothCollisionTriangles(clothCollisionTriangles) { } void simulate(ClothMesh *clothMesh) const @@ -77,17 +75,14 @@ private: std::vector *m_clothMeshes = nullptr; const std::vector *m_clothCollisionVertices = nullptr; const std::vector> *m_clothCollisionTriangles = nullptr; - const std::vector> *m_clothTargetNodes = nullptr; }; void simulateClothMeshes(std::vector *clothMeshes, const std::vector *clothCollisionVertices, - const std::vector> *clothCollisionTriangles, - const std::vector> *clothTargetNodes) + const std::vector> *clothCollisionTriangles) { tbb::parallel_for(tbb::blocked_range(0, clothMeshes->size()), ClothMeshesSimulator(clothMeshes, clothCollisionVertices, - clothCollisionTriangles, - clothTargetNodes)); + clothCollisionTriangles)); } diff --git a/src/simulateclothmeshes.h b/src/simulateclothmeshes.h index 46fc7217..2a9eb9c2 100644 --- a/src/simulateclothmeshes.h +++ b/src/simulateclothmeshes.h @@ -18,7 +18,6 @@ struct ClothMesh void simulateClothMeshes(std::vector *clothMeshes, const std::vector *clothCollisionVertices, - const std::vector> *clothCollisionTriangles, - const std::vector> *clothTargetNodes); + const std::vector> *clothCollisionTriangles); #endif