Fix vertex source node resolving after remesh
parent
ec80f7bacd
commit
8775a09fa3
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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]++;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue