Fix vertex source node resolving after remesh

master
Jeremy Hu 2020-01-17 18:24:27 +09:30
parent ec80f7bacd
commit 8775a09fa3
7 changed files with 32 additions and 32 deletions

View File

@ -1105,9 +1105,6 @@ MeshCombiner::Mesh *MeshGenerator::combineComponentMesh(const QString &component
m_clothCollisionVertices.clear(); m_clothCollisionVertices.clear();
m_clothCollisionTriangles.clear(); m_clothCollisionTriangles.clear();
mesh->fetch(m_clothCollisionVertices, m_clothCollisionTriangles); mesh->fetch(m_clothCollisionVertices, m_clothCollisionTriangles);
buildClothTargetNodes(componentCache.outcomeNodes,
componentCache.outcomeEdges,
&m_clothTargetNodes);
} else { } else {
// TODO: when no body is valid, may add ground plane as collision shape // 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<QVector3D> newVertices; std::vector<QVector3D> newVertices;
std::vector<std::vector<size_t>> newQuads; std::vector<std::vector<size_t>> newQuads;
std::vector<std::vector<size_t>> newTriangles; std::vector<std::vector<size_t>> newTriangles;
std::vector<std::tuple<QVector3D, float, size_t>> interpolatedNodes;
buildInterpolatedNodes(componentCache.outcomeNodes,
componentCache.outcomeEdges,
&interpolatedNodes);
remesh(componentCache.outcomeNodes, remesh(componentCache.outcomeNodes,
interpolatedNodes,
combinedVertices, combinedVertices,
combinedFaces, combinedFaces,
polyCountValue, polyCountValue,
@ -1167,16 +1169,16 @@ MeshCombiner::Mesh *MeshGenerator::combineComponentMesh(const QString &component
return mesh; return mesh;
} }
void MeshGenerator::buildClothTargetNodes(const std::vector<OutcomeNode> &nodes, void MeshGenerator::buildInterpolatedNodes(const std::vector<OutcomeNode> &nodes,
const std::vector<std::pair<std::pair<QUuid, QUuid>, std::pair<QUuid, QUuid>>> &edges, const std::vector<std::pair<std::pair<QUuid, QUuid>, std::pair<QUuid, QUuid>>> &edges,
std::vector<std::pair<QVector3D, float>> *targetNodes) std::vector<std::tuple<QVector3D, float, size_t>> *targetNodes)
{ {
targetNodes->clear(); targetNodes->clear();
std::map<std::pair<QUuid, QUuid>, size_t> nodeMap; std::map<std::pair<QUuid, QUuid>, size_t> nodeMap;
for (size_t nodeIndex = 0; nodeIndex < nodes.size(); ++nodeIndex) { for (size_t nodeIndex = 0; nodeIndex < nodes.size(); ++nodeIndex) {
const auto &it = nodes[nodeIndex]; const auto &it = nodes[nodeIndex];
nodeMap.insert({{it.partId, it.nodeId}, 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) { for (const auto &it: edges) {
auto findFirst = nodeMap.find(it.first); auto findFirst = nodeMap.find(it.first);
@ -1197,9 +1199,10 @@ void MeshGenerator::buildClothTargetNodes(const std::vector<OutcomeNode> &nodes,
float offset = segmentLength; float offset = segmentLength;
while (offset < 1.0f) { while (offset < 1.0f) {
float radius = firstNode.radius * (1.0f - offset) + secondNode.radius * offset; 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, firstNode.origin * (1.0f - offset) + secondNode.origin * offset,
radius * 3.0 radius * 3.0,
offset <= 0.5 ? findFirst->second : findSecond->second
)); ));
offset += segmentLength; offset += segmentLength;
} }
@ -1587,6 +1590,7 @@ void MeshGenerator::generate()
} }
void MeshGenerator::remesh(const std::vector<OutcomeNode> &inputNodes, void MeshGenerator::remesh(const std::vector<OutcomeNode> &inputNodes,
const std::vector<std::tuple<QVector3D, float, size_t>> &interpolatedNodes,
const std::vector<QVector3D> &inputVertices, const std::vector<QVector3D> &inputVertices,
const std::vector<std::vector<size_t>> &inputFaces, const std::vector<std::vector<size_t>> &inputFaces,
float targetVertexMultiplyFactor, float targetVertexMultiplyFactor,
@ -1597,11 +1601,12 @@ void MeshGenerator::remesh(const std::vector<OutcomeNode> &inputNodes,
{ {
std::vector<std::pair<QVector3D, float>> nodes; std::vector<std::pair<QVector3D, float>> nodes;
std::vector<std::pair<QUuid, QUuid>> sourceIds; std::vector<std::pair<QUuid, QUuid>> sourceIds;
nodes.reserve(inputNodes.size()); nodes.reserve(interpolatedNodes.size());
sourceIds.reserve(inputNodes.size()); sourceIds.reserve(interpolatedNodes.size());
for (const auto &it: inputNodes) { for (const auto &it: interpolatedNodes) {
nodes.push_back(std::make_pair(it.origin, it.radius)); nodes.push_back(std::make_pair(std::get<0>(it), std::get<1>(it)));
sourceIds.push_back(std::make_pair(it.partId, it.nodeId)); const auto &sourceNode = inputNodes[std::get<2>(it)];
sourceIds.push_back(std::make_pair(sourceNode.partId, sourceNode.nodeId));
} }
Remesher remesher; Remesher remesher;
remesher.setMesh(inputVertices, inputFaces); remesher.setMesh(inputVertices, inputFaces);
@ -1699,7 +1704,7 @@ void MeshGenerator::collectClothComponentIdStrings(const QString &componentIdStr
void MeshGenerator::collectClothComponent(const QString &componentIdString) void MeshGenerator::collectClothComponent(const QString &componentIdString)
{ {
if (m_clothCollisionTriangles.empty() || m_clothTargetNodes.empty()) if (m_clothCollisionTriangles.empty())
return; return;
std::vector<QString> componentIdStrings; std::vector<QString> componentIdStrings;
@ -1723,8 +1728,7 @@ void MeshGenerator::collectClothComponent(const QString &componentIdString)
} }
simulateClothMeshes(&clothMeshes, simulateClothMeshes(&clothMeshes,
&m_clothCollisionVertices, &m_clothCollisionVertices,
&m_clothCollisionTriangles, &m_clothCollisionTriangles);
&m_clothTargetNodes);
for (auto &clothMesh: clothMeshes) { for (auto &clothMesh: clothMeshes) {
auto vertexStartIndex = m_outcome->vertices.size(); auto vertexStartIndex = m_outcome->vertices.size();
auto updateVertexIndices = [=](std::vector<std::vector<size_t>> &faces) { auto updateVertexIndices = [=](std::vector<std::vector<size_t>> &faces) {

View File

@ -106,7 +106,6 @@ private:
quint64 m_id = 0; quint64 m_id = 0;
std::vector<QVector3D> m_clothCollisionVertices; std::vector<QVector3D> m_clothCollisionVertices;
std::vector<std::vector<size_t>> m_clothCollisionTriangles; std::vector<std::vector<size_t>> m_clothCollisionTriangles;
std::vector<std::pair<QVector3D, float>> m_clothTargetNodes;
void collectParts(); void collectParts();
bool checkIsComponentDirty(const QString &componentIdString); bool checkIsComponentDirty(const QString &componentIdString);
@ -142,6 +141,7 @@ private:
std::vector<QString> *componentIdStrings); std::vector<QString> *componentIdStrings);
void cutFaceStringToCutTemplate(const QString &cutFaceString, std::vector<QVector2D> &cutTemplate); void cutFaceStringToCutTemplate(const QString &cutFaceString, std::vector<QVector2D> &cutTemplate);
void remesh(const std::vector<OutcomeNode> &inputNodes, void remesh(const std::vector<OutcomeNode> &inputNodes,
const std::vector<std::tuple<QVector3D, float, size_t>> &interpolatedNodes,
const std::vector<QVector3D> &inputVertices, const std::vector<QVector3D> &inputVertices,
const std::vector<std::vector<size_t>> &inputFaces, const std::vector<std::vector<size_t>> &inputFaces,
float targetVertexMultiplyFactor, float targetVertexMultiplyFactor,
@ -149,9 +149,9 @@ private:
std::vector<std::vector<size_t>> *outputQuads, std::vector<std::vector<size_t>> *outputQuads,
std::vector<std::vector<size_t>> *outputTriangles, std::vector<std::vector<size_t>> *outputTriangles,
std::vector<std::pair<QVector3D, std::pair<QUuid, QUuid>>> *outputNodeVertices); std::vector<std::pair<QVector3D, std::pair<QUuid, QUuid>>> *outputNodeVertices);
void buildClothTargetNodes(const std::vector<OutcomeNode> &nodes, void buildInterpolatedNodes(const std::vector<OutcomeNode> &nodes,
const std::vector<std::pair<std::pair<QUuid, QUuid>, std::pair<QUuid, QUuid>>> &edges, const std::vector<std::pair<std::pair<QUuid, QUuid>, std::pair<QUuid, QUuid>>> &edges,
std::vector<std::pair<QVector3D, float>> *targetNodes); std::vector<std::tuple<QVector3D, float, size_t>> *targetNodes);
}; };
#endif #endif

View File

@ -383,7 +383,7 @@ void PartTreeWidget::showContextMenu(const QPoint &pos, bool shorted)
std::vector<QUuid> componentIds = collectSelectedComponentIds(pos); std::vector<QUuid> componentIds = collectSelectedComponentIds(pos);
if (shorted) { if (shorted) {
if (componentIds.size() != 1) if (componentIds.size() > 1)
return; return;
} }

View File

@ -69,7 +69,7 @@ void projectFacesToNodes(const std::vector<QVector3D> &vertices,
const std::vector<std::pair<QVector3D, float>> &sourceNodes, const std::vector<std::pair<QVector3D, float>> &sourceNodes,
std::vector<size_t> *faceSources) std::vector<size_t> *faceSources)
{ {
faceSources->resize(faces.size()); faceSources->resize(faces.size(), std::numeric_limits<size_t>::max());
tbb::parallel_for(tbb::blocked_range<size_t>(0, faces.size()), tbb::parallel_for(tbb::blocked_range<size_t>(0, faces.size()),
FacesToNodesProjector(&vertices, &faces, &sourceNodes, faceSources)); FacesToNodesProjector(&vertices, &faces, &sourceNodes, faceSources));
} }

View File

@ -116,6 +116,8 @@ void Remesher::resolveSources()
for (size_t i = 0; i < m_remeshedFaces.size(); ++i) { for (size_t i = 0; i < m_remeshedFaces.size(); ++i) {
const auto &face = m_remeshedFaces[i]; const auto &face = m_remeshedFaces[i];
const auto &source = faceSources[i]; const auto &source = faceSources[i];
if (source >= m_nodes.size())
continue;
for (const auto &vertexIndex: face) for (const auto &vertexIndex: face)
vertexToNodeVotes[vertexIndex][source]++; vertexToNodeVotes[vertexIndex][source]++;
} }

View File

@ -10,12 +10,10 @@ class ClothMeshesSimulator
public: public:
ClothMeshesSimulator(std::vector<ClothMesh> *clothMeshes, ClothMeshesSimulator(std::vector<ClothMesh> *clothMeshes,
const std::vector<QVector3D> *clothCollisionVertices, const std::vector<QVector3D> *clothCollisionVertices,
const std::vector<std::vector<size_t>> *clothCollisionTriangles, const std::vector<std::vector<size_t>> *clothCollisionTriangles) :
const std::vector<std::pair<QVector3D, float>> *clothTargetNodes) :
m_clothMeshes(clothMeshes), m_clothMeshes(clothMeshes),
m_clothCollisionVertices(clothCollisionVertices), m_clothCollisionVertices(clothCollisionVertices),
m_clothCollisionTriangles(clothCollisionTriangles), m_clothCollisionTriangles(clothCollisionTriangles)
m_clothTargetNodes(clothTargetNodes)
{ {
} }
void simulate(ClothMesh *clothMesh) const void simulate(ClothMesh *clothMesh) const
@ -77,17 +75,14 @@ private:
std::vector<ClothMesh> *m_clothMeshes = nullptr; std::vector<ClothMesh> *m_clothMeshes = nullptr;
const std::vector<QVector3D> *m_clothCollisionVertices = nullptr; const std::vector<QVector3D> *m_clothCollisionVertices = nullptr;
const std::vector<std::vector<size_t>> *m_clothCollisionTriangles = nullptr; const std::vector<std::vector<size_t>> *m_clothCollisionTriangles = nullptr;
const std::vector<std::pair<QVector3D, float>> *m_clothTargetNodes = nullptr;
}; };
void simulateClothMeshes(std::vector<ClothMesh> *clothMeshes, void simulateClothMeshes(std::vector<ClothMesh> *clothMeshes,
const std::vector<QVector3D> *clothCollisionVertices, const std::vector<QVector3D> *clothCollisionVertices,
const std::vector<std::vector<size_t>> *clothCollisionTriangles, const std::vector<std::vector<size_t>> *clothCollisionTriangles)
const std::vector<std::pair<QVector3D, float>> *clothTargetNodes)
{ {
tbb::parallel_for(tbb::blocked_range<size_t>(0, clothMeshes->size()), tbb::parallel_for(tbb::blocked_range<size_t>(0, clothMeshes->size()),
ClothMeshesSimulator(clothMeshes, ClothMeshesSimulator(clothMeshes,
clothCollisionVertices, clothCollisionVertices,
clothCollisionTriangles, clothCollisionTriangles));
clothTargetNodes));
} }

View File

@ -18,7 +18,6 @@ struct ClothMesh
void simulateClothMeshes(std::vector<ClothMesh> *clothMeshes, void simulateClothMeshes(std::vector<ClothMesh> *clothMeshes,
const std::vector<QVector3D> *clothCollisionVertices, const std::vector<QVector3D> *clothCollisionVertices,
const std::vector<std::vector<size_t>> *clothCollisionTriangles, const std::vector<std::vector<size_t>> *clothCollisionTriangles);
const std::vector<std::pair<QVector3D, float>> *clothTargetNodes);
#endif #endif