Add intermediate bone remover.
- Remove intermediate bones when user marked leg nodes - Add flags to toggle gltf comment and normal output - Fix face normal - Adjust the skeleton bone mesh radiusmaster
parent
bed110b678
commit
c4505ba788
|
@ -128,6 +128,9 @@ HEADERS += src/markiconcreator.h
|
|||
SOURCES += src/skeletonbonemark.cpp
|
||||
HEADERS += src/skeletonbonemark.h
|
||||
|
||||
SOURCES += src/intermediateboneremover.cpp
|
||||
HEADERS += src/intermediateboneremover.h
|
||||
|
||||
HEADERS += src/qtlightmapper.h
|
||||
|
||||
SOURCES += src/main.cpp
|
||||
|
|
|
@ -17,8 +17,11 @@
|
|||
// http://quaternions.online/
|
||||
// https://en.m.wikipedia.org/wiki/Rotation_formalisms_in_three_dimensions?wprov=sfla1
|
||||
|
||||
bool GLTFFileWriter::m_enableComment = false;
|
||||
|
||||
GLTFFileWriter::GLTFFileWriter(MeshResultContext &resultContext, const QString &filename) :
|
||||
m_filename(filename)
|
||||
m_filename(filename),
|
||||
m_outputNormal(true)
|
||||
{
|
||||
const BmeshNode *rootNode = resultContext.centerBmeshNode();
|
||||
if (!rootNode) {
|
||||
|
@ -107,6 +110,8 @@ GLTFFileWriter::GLTFFileWriter(MeshResultContext &resultContext, const QString &
|
|||
|
||||
int bufferViewIndex = 0;
|
||||
|
||||
if (m_enableComment)
|
||||
m_json["accessors"][bufferViewIndex]["__comment"] = QString("/accessors/%1: mat").arg(QString::number(bufferViewIndex)).toUtf8().constData();
|
||||
m_json["accessors"][bufferViewIndex]["bufferView"] = bufferViewIndex;
|
||||
m_json["accessors"][bufferViewIndex]["byteOffset"] = 0;
|
||||
m_json["accessors"][bufferViewIndex]["componentType"] = 5126;
|
||||
|
@ -140,12 +145,14 @@ GLTFFileWriter::GLTFFileWriter(MeshResultContext &resultContext, const QString &
|
|||
int bufferViewFromOffset;
|
||||
|
||||
m_json["meshes"][0]["primitives"][primitiveIndex]["indices"] = bufferViewIndex;
|
||||
m_json["meshes"][0]["primitives"][primitiveIndex]["attributes"]["POSITION"] = bufferViewIndex + 1;
|
||||
m_json["meshes"][0]["primitives"][primitiveIndex]["attributes"]["NORMAL"] = bufferViewIndex + 2;
|
||||
m_json["meshes"][0]["primitives"][primitiveIndex]["attributes"]["JOINTS_0"] = bufferViewIndex + 3;
|
||||
m_json["meshes"][0]["primitives"][primitiveIndex]["attributes"]["WEIGHTS_0"] = bufferViewIndex + 4;
|
||||
m_json["meshes"][0]["primitives"][primitiveIndex]["attributes"]["TEXCOORD_0"] = bufferViewIndex + 5;
|
||||
m_json["meshes"][0]["primitives"][primitiveIndex]["material"] = primitiveIndex;
|
||||
int attributeIndex = 0;
|
||||
m_json["meshes"][0]["primitives"][primitiveIndex]["attributes"]["POSITION"] = bufferViewIndex + (++attributeIndex);
|
||||
if (m_outputNormal)
|
||||
m_json["meshes"][0]["primitives"][primitiveIndex]["attributes"]["NORMAL"] = bufferViewIndex + (++attributeIndex);
|
||||
m_json["meshes"][0]["primitives"][primitiveIndex]["attributes"]["JOINTS_0"] = bufferViewIndex + (++attributeIndex);
|
||||
m_json["meshes"][0]["primitives"][primitiveIndex]["attributes"]["WEIGHTS_0"] = bufferViewIndex + (++attributeIndex);
|
||||
m_json["meshes"][0]["primitives"][primitiveIndex]["attributes"]["TEXCOORD_0"] = bufferViewIndex + (++attributeIndex);
|
||||
/*
|
||||
m_json["materials"][primitiveIndex]["pbrMetallicRoughness"]["baseColorFactor"] = {
|
||||
part.second.color.redF(),
|
||||
|
@ -169,6 +176,8 @@ GLTFFileWriter::GLTFFileWriter(MeshResultContext &resultContext, const QString &
|
|||
m_json["bufferViews"][bufferViewIndex]["target"] = 34963;
|
||||
Q_ASSERT(part.second.triangles.size() * 3 * sizeof(quint16) == binaries.size() - bufferViewFromOffset);
|
||||
alignBinaries();
|
||||
if (m_enableComment)
|
||||
m_json["accessors"][bufferViewIndex]["__comment"] = QString("/accessors/%1: triangle indicies").arg(QString::number(bufferViewIndex)).toUtf8().constData();
|
||||
m_json["accessors"][bufferViewIndex]["bufferView"] = bufferViewIndex;
|
||||
m_json["accessors"][bufferViewIndex]["byteOffset"] = 0;
|
||||
m_json["accessors"][bufferViewIndex]["componentType"] = 5123;
|
||||
|
@ -204,7 +213,8 @@ GLTFFileWriter::GLTFFileWriter(MeshResultContext &resultContext, const QString &
|
|||
m_json["bufferViews"][bufferViewIndex]["byteLength"] = part.second.vertices.size() * 3 * sizeof(float);
|
||||
m_json["bufferViews"][bufferViewIndex]["target"] = 34962;
|
||||
alignBinaries();
|
||||
|
||||
if (m_enableComment)
|
||||
m_json["accessors"][bufferViewIndex]["__comment"] = QString("/accessors/%1: xyz").arg(QString::number(bufferViewIndex)).toUtf8().constData();
|
||||
m_json["accessors"][bufferViewIndex]["bufferView"] = bufferViewIndex;
|
||||
m_json["accessors"][bufferViewIndex]["byteOffset"] = 0;
|
||||
m_json["accessors"][bufferViewIndex]["componentType"] = 5126;
|
||||
|
@ -214,23 +224,29 @@ GLTFFileWriter::GLTFFileWriter(MeshResultContext &resultContext, const QString &
|
|||
m_json["accessors"][bufferViewIndex]["min"] = {minX, minY, minZ};
|
||||
bufferViewIndex++;
|
||||
|
||||
if (m_outputNormal) {
|
||||
bufferViewFromOffset = (int)binaries.size();
|
||||
m_json["bufferViews"][bufferViewIndex]["buffer"] = 0;
|
||||
m_json["bufferViews"][bufferViewIndex]["byteOffset"] = bufferViewFromOffset;
|
||||
QStringList normalList;
|
||||
for (const auto &it: part.second.interpolatedVertexNormals) {
|
||||
stream << (float)it.x() << (float)it.y() << (float)it.z();
|
||||
if (m_outputNormal)
|
||||
normalList.append(QString("<%1,%2,%3>").arg(QString::number(it.x())).arg(QString::number(it.y())).arg(QString::number(it.z())));
|
||||
}
|
||||
Q_ASSERT( part.second.interpolatedVertexNormals.size() * 3 * sizeof(float) == binaries.size() - bufferViewFromOffset);
|
||||
m_json["bufferViews"][bufferViewIndex]["byteLength"] = part.second.vertices.size() * 3 * sizeof(float);
|
||||
m_json["bufferViews"][bufferViewIndex]["target"] = 34962;
|
||||
alignBinaries();
|
||||
|
||||
if (m_enableComment)
|
||||
m_json["accessors"][bufferViewIndex]["__comment"] = QString("/accessors/%1: normal %2").arg(QString::number(bufferViewIndex)).arg(normalList.join(" ")).toUtf8().constData();
|
||||
m_json["accessors"][bufferViewIndex]["bufferView"] = bufferViewIndex;
|
||||
m_json["accessors"][bufferViewIndex]["byteOffset"] = 0;
|
||||
m_json["accessors"][bufferViewIndex]["componentType"] = 5126;
|
||||
m_json["accessors"][bufferViewIndex]["count"] = part.second.vertices.size();
|
||||
m_json["accessors"][bufferViewIndex]["type"] = "VEC3";
|
||||
bufferViewIndex++;
|
||||
}
|
||||
|
||||
bufferViewFromOffset = (int)binaries.size();
|
||||
m_json["bufferViews"][bufferViewIndex]["buffer"] = 0;
|
||||
|
@ -246,6 +262,8 @@ GLTFFileWriter::GLTFFileWriter(MeshResultContext &resultContext, const QString &
|
|||
}
|
||||
m_json["bufferViews"][bufferViewIndex]["byteLength"] = binaries.size() - bufferViewFromOffset;
|
||||
alignBinaries();
|
||||
if (m_enableComment)
|
||||
m_json["accessors"][bufferViewIndex]["__comment"] = QString("/accessors/%1: bone indicies").arg(QString::number(bufferViewIndex)).toUtf8().constData();
|
||||
m_json["accessors"][bufferViewIndex]["bufferView"] = bufferViewIndex;
|
||||
m_json["accessors"][bufferViewIndex]["byteOffset"] = 0;
|
||||
m_json["accessors"][bufferViewIndex]["componentType"] = 5123;
|
||||
|
@ -267,6 +285,8 @@ GLTFFileWriter::GLTFFileWriter(MeshResultContext &resultContext, const QString &
|
|||
}
|
||||
m_json["bufferViews"][bufferViewIndex]["byteLength"] = binaries.size() - bufferViewFromOffset;
|
||||
alignBinaries();
|
||||
if (m_enableComment)
|
||||
m_json["accessors"][bufferViewIndex]["__comment"] = QString("/accessors/%1: bone weights").arg(QString::number(bufferViewIndex)).toUtf8().constData();
|
||||
m_json["accessors"][bufferViewIndex]["bufferView"] = bufferViewIndex;
|
||||
m_json["accessors"][bufferViewIndex]["byteOffset"] = 0;
|
||||
m_json["accessors"][bufferViewIndex]["componentType"] = 5126;
|
||||
|
@ -282,6 +302,8 @@ GLTFFileWriter::GLTFFileWriter(MeshResultContext &resultContext, const QString &
|
|||
}
|
||||
m_json["bufferViews"][bufferViewIndex]["byteLength"] = binaries.size() - bufferViewFromOffset;
|
||||
alignBinaries();
|
||||
if (m_enableComment)
|
||||
m_json["accessors"][bufferViewIndex]["__comment"] = QString("/accessors/%1: uv").arg(QString::number(bufferViewIndex)).toUtf8().constData();
|
||||
m_json["accessors"][bufferViewIndex]["bufferView"] = bufferViewIndex;
|
||||
m_json["accessors"][bufferViewIndex]["byteOffset"] = 0;
|
||||
m_json["accessors"][bufferViewIndex]["componentType"] = 5126;
|
||||
|
|
|
@ -36,8 +36,11 @@ private:
|
|||
QString getMatrixStringInColumnOrder(const QMatrix4x4 &mat);
|
||||
QString m_filename;
|
||||
QString m_textureFilename;
|
||||
bool m_outputNormal;
|
||||
private:
|
||||
nlohmann::json m_json;
|
||||
public:
|
||||
static bool m_enableComment;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
#include "intermediateboneremover.h"
|
||||
|
||||
void IntermediateBoneRemover::addEdge(int fromPartId, int fromNodeId, int toPartId, int toNodeId)
|
||||
{
|
||||
auto &neighborMap = m_neighborMap[std::make_pair(fromPartId, fromNodeId)];
|
||||
neighborMap.push_back(std::make_pair(toPartId, toNodeId));
|
||||
}
|
||||
|
||||
const std::map<std::pair<int, int>, IntermediateBoneNode> &IntermediateBoneRemover::intermediateNodes()
|
||||
{
|
||||
return m_intermediateNodes;
|
||||
}
|
||||
|
||||
const std::vector<std::tuple<int, int, int, int>> &IntermediateBoneRemover::newEdges()
|
||||
{
|
||||
return m_newEdges;
|
||||
}
|
||||
|
||||
void IntermediateBoneRemover::markNodeAsStart(int partId, int nodeId)
|
||||
{
|
||||
m_startNodeSet.insert(std::make_pair(partId, nodeId));
|
||||
}
|
||||
|
||||
void IntermediateBoneRemover::markNodeAsEssential(int partId, int nodeId)
|
||||
{
|
||||
m_essentialNodeSet.insert(std::make_pair(partId, nodeId));
|
||||
}
|
||||
|
||||
void IntermediateBoneRemover::solveFrom(int partId, int nodeId)
|
||||
{
|
||||
std::pair<int, int> pair = std::make_pair(partId, nodeId);
|
||||
std::vector<std::pair<int, int>> trace;
|
||||
solveFromPairAndSaveTraceTo(pair, trace);
|
||||
}
|
||||
|
||||
void IntermediateBoneRemover::addNeighborsOfIntermediateNodeFrom(std::pair<int, int> node, const IntermediateBoneNode &source)
|
||||
{
|
||||
if (m_addedSet.find(node) != m_addedSet.end())
|
||||
return;
|
||||
m_addedSet.insert(node);
|
||||
if (m_essentialNodeSet.find(node) != m_essentialNodeSet.end() ||
|
||||
m_startNodeSet.find(node) != m_startNodeSet.end())
|
||||
return;
|
||||
IntermediateBoneNode intermediate = source;
|
||||
intermediate.partId = node.first;
|
||||
intermediate.nodeId = node.second;
|
||||
m_intermediateNodes[std::make_pair(intermediate.partId, intermediate.nodeId)] = intermediate;
|
||||
const auto &it = m_neighborMap.find(node);
|
||||
if (it == m_neighborMap.end())
|
||||
return;
|
||||
for (const auto &neighbor: it->second) {
|
||||
addNeighborsOfIntermediateNodeFrom(neighbor, source);
|
||||
}
|
||||
}
|
||||
|
||||
void IntermediateBoneRemover::solveFromPairAndSaveTraceTo(std::pair<int, int> node, std::vector<std::pair<int, int>> &history)
|
||||
{
|
||||
if (m_solvedSet.find(node) != m_solvedSet.end())
|
||||
return;
|
||||
m_solvedSet.insert(node);
|
||||
if (m_essentialNodeSet.find(node) != m_essentialNodeSet.end()) {
|
||||
for (int i = history.size() - 1; i >= 0; i--) {
|
||||
if (m_essentialNodeSet.find(history[i]) != m_essentialNodeSet.end() ||
|
||||
m_startNodeSet.find(history[i]) != m_startNodeSet.end()) {
|
||||
IntermediateBoneNode intermediate;
|
||||
intermediate.attachedFromPartId = history[i].first;
|
||||
intermediate.attachedFromNodeId = history[i].second;
|
||||
intermediate.attachedToPartId = node.first;
|
||||
intermediate.attachedToNodeId = node.second;
|
||||
int removedNodeNum = 0;
|
||||
for (int j = i + 1; j <= (int)history.size() - 1; j++) {
|
||||
intermediate.partId = history[j].first;
|
||||
intermediate.nodeId = history[j].second;
|
||||
removedNodeNum++;
|
||||
m_intermediateNodes[std::make_pair(intermediate.partId, intermediate.nodeId)] = intermediate;
|
||||
addNeighborsOfIntermediateNodeFrom(std::make_pair(intermediate.partId, intermediate.nodeId), intermediate);
|
||||
}
|
||||
if (removedNodeNum > 0) {
|
||||
m_newEdges.push_back(std::make_tuple(intermediate.attachedFromPartId,
|
||||
intermediate.attachedFromNodeId,
|
||||
intermediate.attachedToPartId,
|
||||
intermediate.attachedToNodeId));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
history.push_back(node);
|
||||
const auto &it = m_neighborMap.find(node);
|
||||
if (it == m_neighborMap.end())
|
||||
return;
|
||||
for (const auto &neighbor: it->second) {
|
||||
std::vector<std::pair<int, int>> subHistory = history;
|
||||
solveFromPairAndSaveTraceTo(neighbor, subHistory);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef INTERMEDIATE_BONE_REMOVER_H
|
||||
#define INTERMEDIATE_BONE_REMOVER_H
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
struct IntermediateBoneNode
|
||||
{
|
||||
int partId;
|
||||
int nodeId;
|
||||
int attachedFromPartId;
|
||||
int attachedFromNodeId;
|
||||
int attachedToPartId;
|
||||
int attachedToNodeId;
|
||||
};
|
||||
|
||||
class IntermediateBoneRemover
|
||||
{
|
||||
public:
|
||||
void addEdge(int fromPartId, int fromNodeId, int toPartId, int toNodeId);
|
||||
void markNodeAsStart(int partId, int nodeId);
|
||||
void markNodeAsEssential(int partId, int nodeId);
|
||||
void solveFrom(int partId, int nodeId);
|
||||
const std::map<std::pair<int, int>, IntermediateBoneNode> &intermediateNodes();
|
||||
const std::vector<std::tuple<int, int, int, int>> &newEdges();
|
||||
private:
|
||||
void solveFromPairAndSaveTraceTo(std::pair<int, int> node, std::vector<std::pair<int, int>> &history);
|
||||
void addNeighborsOfIntermediateNodeFrom(std::pair<int, int> node, const IntermediateBoneNode &source);
|
||||
std::map<std::pair<int, int>, IntermediateBoneNode> m_intermediateNodes;
|
||||
std::set<std::pair<int, int>> m_startNodeSet;
|
||||
std::set<std::pair<int, int>> m_essentialNodeSet;
|
||||
std::map<std::pair<int, int>, std::vector<std::pair<int, int>>> m_neighborMap;
|
||||
std::set<std::pair<int, int>> m_solvedSet;
|
||||
std::vector<std::tuple<int, int, int, int>> m_newEdges;
|
||||
std::set<std::pair<int, int>> m_addedSet;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -401,6 +401,7 @@ const std::map<std::pair<int, int>, std::vector<std::pair<int, int>>> &MeshResul
|
|||
|
||||
void MeshResultContext::calculateBmeshNodeNeighbors(std::map<std::pair<int, int>, std::vector<std::pair<int, int>>> &nodeNeighbors)
|
||||
{
|
||||
nodeNeighbors.clear();
|
||||
for (const auto &it: bmeshEdges) {
|
||||
nodeNeighbors[std::make_pair(it.fromBmeshId, it.fromNodeId)].push_back(std::make_pair(it.toBmeshId, it.toNodeId));
|
||||
nodeNeighbors[std::make_pair(it.toBmeshId, it.toNodeId)].push_back(std::make_pair(it.fromBmeshId, it.fromNodeId));
|
||||
|
@ -459,7 +460,7 @@ const std::vector<std::vector<ResultVertexWeight>> &MeshResultContext::vertexWei
|
|||
return m_resultVertexWeights;
|
||||
}
|
||||
|
||||
void MeshResultContext::calculateVertexWeights(std::vector<std::vector<ResultVertexWeight>> &vertexWeights)
|
||||
void MeshResultContext::calculateVertexWeights(std::vector<std::vector<ResultVertexWeight>> &vertexWeights, const std::map<std::pair<int, int>, IntermediateBoneNode> *intermediateNodes)
|
||||
{
|
||||
vertexWeights.clear();
|
||||
vertexWeights.resize(vertices.size());
|
||||
|
@ -493,6 +494,48 @@ void MeshResultContext::calculateVertexWeights(std::vector<std::vector<ResultVer
|
|||
it[i].weight = (float)it[i].count / total;
|
||||
}
|
||||
}
|
||||
if (nullptr != intermediateNodes) {
|
||||
// We removed some intermediate nodes, so we should recalculate the vertex weights.
|
||||
for (auto &it: vertexWeights) {
|
||||
std::vector<std::pair<std::pair<int, int>, float>> weights;
|
||||
for (auto i = 0u; i < it.size(); i++) {
|
||||
const auto &findInter = intermediateNodes->find(it[i].sourceNode);
|
||||
if (findInter != intermediateNodes->end()) {
|
||||
const auto &interBmeshNode = bmeshNodeMap().find(findInter->first);
|
||||
const auto &attachedFromBmeshNode = bmeshNodeMap().find(std::make_pair(findInter->second.attachedFromPartId, findInter->second.attachedFromNodeId));
|
||||
const auto &attachedToBmeshNode = bmeshNodeMap().find(std::make_pair(findInter->second.attachedToPartId, findInter->second.attachedToNodeId));
|
||||
if (interBmeshNode != bmeshNodeMap().end() &&
|
||||
attachedFromBmeshNode != bmeshNodeMap().end() &&
|
||||
attachedToBmeshNode != bmeshNodeMap().end()) {
|
||||
float distWithFrom = interBmeshNode->second->origin.distanceToPoint(attachedFromBmeshNode->second->origin);
|
||||
float distWithTo = interBmeshNode->second->origin.distanceToPoint(attachedToBmeshNode->second->origin);
|
||||
float distTotal = distWithFrom + distWithTo;
|
||||
if (distTotal > 0) {
|
||||
weights.push_back(std::make_pair(attachedFromBmeshNode->first, it[i].weight * distWithFrom / distTotal));
|
||||
weights.push_back(std::make_pair(attachedToBmeshNode->first, it[i].weight * distWithTo / distTotal));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
weights.push_back(std::make_pair(it[i].sourceNode, it[i].weight));
|
||||
}
|
||||
}
|
||||
std::sort(weights.begin(), weights.end(), [](const std::pair<std::pair<int, int>, float> &a, const std::pair<std::pair<int, int>, float> &b) -> bool {
|
||||
return a.second > b.second;
|
||||
});
|
||||
float total = 0;
|
||||
for (auto i = 0u; i < MAX_WEIGHT_NUM && i < weights.size(); i++) {
|
||||
total += weights[i].second;
|
||||
}
|
||||
for (auto i = 0u; i < MAX_WEIGHT_NUM && i < weights.size(); i++) {
|
||||
weights[i].second = weights[i].second / total;
|
||||
}
|
||||
for (auto i = 0u; i < MAX_WEIGHT_NUM && i < weights.size(); i++) {
|
||||
it[i].sourceNode = weights[i].first;
|
||||
it[i].weight = weights[i].second;
|
||||
it[i].count = -1; // no use
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::map<int, ResultPart> &MeshResultContext::parts()
|
||||
|
@ -716,3 +759,46 @@ void MeshResultContext::calculateResultRearrangedVertices(std::vector<ResultRear
|
|||
rearrangedTriangles.push_back(newTriangle);
|
||||
}
|
||||
}
|
||||
|
||||
void MeshResultContext::removeIntermediateBones()
|
||||
{
|
||||
Q_ASSERT(m_vertexWeightsResolved);
|
||||
Q_ASSERT(m_bmeshNodeNeighborsResolved);
|
||||
IntermediateBoneRemover remover;
|
||||
for (const auto &edge: bmeshEdges) {
|
||||
remover.addEdge(edge.fromBmeshId, edge.fromNodeId, edge.toBmeshId, edge.toNodeId);
|
||||
}
|
||||
for (const auto &node: bmeshNodes) {
|
||||
if (SkeletonBoneMarkIsStart(node.boneMark)) {
|
||||
remover.markNodeAsStart(node.bmeshId, node.nodeId);
|
||||
} else if (SkeletonBoneMark::None != node.boneMark) {
|
||||
remover.markNodeAsEssential(node.bmeshId, node.nodeId);
|
||||
}
|
||||
}
|
||||
const BmeshNode *centerNode = centerBmeshNode();
|
||||
if (nullptr == centerNode)
|
||||
return;
|
||||
remover.solveFrom(centerNode->bmeshId, centerNode->nodeId);
|
||||
|
||||
const auto &intermediateNodes = remover.intermediateNodes();
|
||||
|
||||
calculateVertexWeights(m_resultVertexWeights, &intermediateNodes);
|
||||
|
||||
const auto oldEdges = bmeshEdges;
|
||||
bmeshEdges.clear();
|
||||
for (const auto &old: oldEdges) {
|
||||
if (intermediateNodes.find(std::make_pair(old.fromBmeshId, old.fromNodeId)) != intermediateNodes.end() ||
|
||||
intermediateNodes.find(std::make_pair(old.toBmeshId, old.toNodeId)) != intermediateNodes.end())
|
||||
continue;
|
||||
bmeshEdges.push_back(old);
|
||||
}
|
||||
for (const auto &edge: remover.newEdges()) {
|
||||
BmeshEdge newEdge;
|
||||
newEdge.fromBmeshId = std::get<0>(edge);
|
||||
newEdge.fromNodeId = std::get<1>(edge);
|
||||
newEdge.toBmeshId = std::get<2>(edge);
|
||||
newEdge.toNodeId = std::get<3>(edge);
|
||||
bmeshEdges.push_back(newEdge);
|
||||
}
|
||||
calculateBmeshNodeNeighbors(m_nodeNeighbors);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <QColor>
|
||||
#include "positionmap.h"
|
||||
#include "skeletonbonemark.h"
|
||||
#include "intermediateboneremover.h"
|
||||
|
||||
#define MAX_WEIGHT_NUM 4
|
||||
|
||||
|
@ -117,6 +118,7 @@ public:
|
|||
const std::vector<ResultTriangleUv> &triangleUvs();
|
||||
const std::vector<ResultRearrangedVertex> &rearrangedVertices();
|
||||
const std::vector<ResultRearrangedTriangle> &rearrangedTriangles();
|
||||
void removeIntermediateBones();
|
||||
private:
|
||||
bool m_triangleSourceResolved;
|
||||
bool m_triangleColorResolved;
|
||||
|
@ -154,7 +156,7 @@ private:
|
|||
void calculateBmeshNodeNeighbors();
|
||||
void calculateBmeshEdgeDirectionsFromNode(std::pair<int, int> node, std::set<std::pair<int, int>> &visitedNodes, std::set<std::pair<std::pair<int, int>, std::pair<int, int>>> &connections, std::vector<BmeshEdge> &rearrangedEdges);
|
||||
void calculateBmeshNodeNeighbors(std::map<std::pair<int, int>, std::vector<std::pair<int, int>>> &nodeNeighbors);
|
||||
void calculateVertexWeights(std::vector<std::vector<ResultVertexWeight>> &vertexWeights);
|
||||
void calculateVertexWeights(std::vector<std::vector<ResultVertexWeight>> &vertexWeights, const std::map<std::pair<int, int>, IntermediateBoneNode> *intermediateNodes=nullptr);
|
||||
void calculateResultParts(std::map<int, ResultPart> &parts);
|
||||
void calculateResultTriangleUvs(std::vector<ResultTriangleUv> &uvs, std::set<int> &seamVertices);
|
||||
void calculateResultRearrangedVertices(std::vector<ResultRearrangedVertex> &rearrangedVertices, std::vector<ResultRearrangedTriangle> &rearrangedTriangles);
|
||||
|
|
|
@ -24,6 +24,8 @@ void MeshResultPostProcessor::process()
|
|||
if (!m_meshResultContext->bmeshNodes.empty()) {
|
||||
m_meshResultContext->resolveBmeshConnectivity();
|
||||
m_meshResultContext->resolveBmeshEdgeDirections();
|
||||
m_meshResultContext->vertexWeights();
|
||||
m_meshResultContext->removeIntermediateBones();
|
||||
m_meshResultContext->rearrangedVertices();
|
||||
m_meshResultContext->rearrangedTriangles();
|
||||
m_meshResultContext->parts();
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue