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_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<QVector3D> newVertices;
std::vector<std::vector<size_t>> newQuads;
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,
interpolatedNodes,
combinedVertices,
combinedFaces,
polyCountValue,
@ -1167,16 +1169,16 @@ MeshCombiner::Mesh *MeshGenerator::combineComponentMesh(const QString &component
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,
std::vector<std::pair<QVector3D, float>> *targetNodes)
std::vector<std::tuple<QVector3D, float, size_t>> *targetNodes)
{
targetNodes->clear();
std::map<std::pair<QUuid, QUuid>, 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<OutcomeNode> &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<OutcomeNode> &inputNodes,
const std::vector<std::tuple<QVector3D, float, size_t>> &interpolatedNodes,
const std::vector<QVector3D> &inputVertices,
const std::vector<std::vector<size_t>> &inputFaces,
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<QUuid, QUuid>> 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<QString> 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<std::vector<size_t>> &faces) {

View File

@ -106,7 +106,6 @@ private:
quint64 m_id = 0;
std::vector<QVector3D> m_clothCollisionVertices;
std::vector<std::vector<size_t>> m_clothCollisionTriangles;
std::vector<std::pair<QVector3D, float>> m_clothTargetNodes;
void collectParts();
bool checkIsComponentDirty(const QString &componentIdString);
@ -142,6 +141,7 @@ private:
std::vector<QString> *componentIdStrings);
void cutFaceStringToCutTemplate(const QString &cutFaceString, std::vector<QVector2D> &cutTemplate);
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<std::vector<size_t>> &inputFaces,
float targetVertexMultiplyFactor,
@ -149,9 +149,9 @@ private:
std::vector<std::vector<size_t>> *outputQuads,
std::vector<std::vector<size_t>> *outputTriangles,
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,
std::vector<std::pair<QVector3D, float>> *targetNodes);
std::vector<std::tuple<QVector3D, float, size_t>> *targetNodes);
};
#endif

View File

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

View File

@ -69,7 +69,7 @@ void projectFacesToNodes(const std::vector<QVector3D> &vertices,
const std::vector<std::pair<QVector3D, float>> &sourceNodes,
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()),
FacesToNodesProjector(&vertices, &faces, &sourceNodes, faceSources));
}

View File

@ -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]++;
}

View File

@ -10,12 +10,10 @@ class ClothMeshesSimulator
public:
ClothMeshesSimulator(std::vector<ClothMesh> *clothMeshes,
const std::vector<QVector3D> *clothCollisionVertices,
const std::vector<std::vector<size_t>> *clothCollisionTriangles,
const std::vector<std::pair<QVector3D, float>> *clothTargetNodes) :
const std::vector<std::vector<size_t>> *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<ClothMesh> *m_clothMeshes = nullptr;
const std::vector<QVector3D> *m_clothCollisionVertices = 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,
const std::vector<QVector3D> *clothCollisionVertices,
const std::vector<std::vector<size_t>> *clothCollisionTriangles,
const std::vector<std::pair<QVector3D, float>> *clothTargetNodes)
const std::vector<std::vector<size_t>> *clothCollisionTriangles)
{
tbb::parallel_for(tbb::blocked_range<size_t>(0, clothMeshes->size()),
ClothMeshesSimulator(clothMeshes,
clothCollisionVertices,
clothCollisionTriangles,
clothTargetNodes));
clothCollisionTriangles));
}

View File

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