Fix typo
parent
538528d103
commit
f6bafdb720
|
@ -8,29 +8,29 @@ void angleSmooth(const std::vector<QVector3D> &vertices,
|
||||||
const std::vector<QVector3D> &triangleNormals,
|
const std::vector<QVector3D> &triangleNormals,
|
||||||
float thresholdAngleDegrees, std::vector<QVector3D> &triangleVertexNormals)
|
float thresholdAngleDegrees, std::vector<QVector3D> &triangleVertexNormals)
|
||||||
{
|
{
|
||||||
std::vector<std::vector<std::pair<size_t, size_t>>> triangleVertexNormalsMapByIndicies(vertices.size());
|
std::vector<std::vector<std::pair<size_t, size_t>>> triangleVertexNormalsMapByIndices(vertices.size());
|
||||||
std::vector<QVector3D> angleAreaWeightedNormals;
|
std::vector<QVector3D> angleAreaWeightedNormals;
|
||||||
for (size_t triangleIndex = 0; triangleIndex < triangles.size(); ++triangleIndex) {
|
for (size_t triangleIndex = 0; triangleIndex < triangles.size(); ++triangleIndex) {
|
||||||
const auto &sourceTriangle = triangles[triangleIndex];
|
const auto &sourceTriangle = triangles[triangleIndex];
|
||||||
size_t indicies[] = {std::get<0>(sourceTriangle),
|
size_t indices[] = {std::get<0>(sourceTriangle),
|
||||||
std::get<1>(sourceTriangle),
|
std::get<1>(sourceTriangle),
|
||||||
std::get<2>(sourceTriangle)};
|
std::get<2>(sourceTriangle)};
|
||||||
const auto &v1 = vertices[indicies[0]];
|
const auto &v1 = vertices[indices[0]];
|
||||||
const auto &v2 = vertices[indicies[1]];
|
const auto &v2 = vertices[indices[1]];
|
||||||
const auto &v3 = vertices[indicies[2]];
|
const auto &v3 = vertices[indices[2]];
|
||||||
float area = areaOfTriangle(v1, v2, v3);
|
float area = areaOfTriangle(v1, v2, v3);
|
||||||
float angles[] = {radianBetweenVectors(v2-v1, v3-v1),
|
float angles[] = {radianBetweenVectors(v2-v1, v3-v1),
|
||||||
radianBetweenVectors(v1-v2, v3-v2),
|
radianBetweenVectors(v1-v2, v3-v2),
|
||||||
radianBetweenVectors(v1-v3, v2-v3)};
|
radianBetweenVectors(v1-v3, v2-v3)};
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
triangleVertexNormalsMapByIndicies[indicies[i]].push_back({triangleIndex, angleAreaWeightedNormals.size()});
|
triangleVertexNormalsMapByIndices[indices[i]].push_back({triangleIndex, angleAreaWeightedNormals.size()});
|
||||||
angleAreaWeightedNormals.push_back(triangleNormals[triangleIndex] * area * angles[i]);
|
angleAreaWeightedNormals.push_back(triangleNormals[triangleIndex] * area * angles[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
triangleVertexNormals = angleAreaWeightedNormals;
|
triangleVertexNormals = angleAreaWeightedNormals;
|
||||||
std::map<std::pair<size_t, size_t>, float> degreesBetweenFacesMap;
|
std::map<std::pair<size_t, size_t>, float> degreesBetweenFacesMap;
|
||||||
for (size_t vertexIndex = 0; vertexIndex < vertices.size(); ++vertexIndex) {
|
for (size_t vertexIndex = 0; vertexIndex < vertices.size(); ++vertexIndex) {
|
||||||
const auto &triangleVertices = triangleVertexNormalsMapByIndicies[vertexIndex];
|
const auto &triangleVertices = triangleVertexNormalsMapByIndices[vertexIndex];
|
||||||
for (const auto &triangleVertex: triangleVertices) {
|
for (const auto &triangleVertex: triangleVertices) {
|
||||||
for (const auto &otherTriangleVertex: triangleVertices) {
|
for (const auto &otherTriangleVertex: triangleVertices) {
|
||||||
if (triangleVertex.first == otherTriangleVertex.first)
|
if (triangleVertex.first == otherTriangleVertex.first)
|
||||||
|
|
|
@ -31,11 +31,11 @@ BoneMark AnimalRigger::translateBoneMark(BoneMark boneMark)
|
||||||
return boneMark;
|
return boneMark;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AnimalRigger::collectJontsForChain(int markIndex, std::vector<int> &jointMarkIndicies)
|
bool AnimalRigger::collectJontsForChain(int markIndex, std::vector<int> &jointMarkIndices)
|
||||||
{
|
{
|
||||||
const auto &mark = m_marks[markIndex];
|
const auto &mark = m_marks[markIndex];
|
||||||
|
|
||||||
jointMarkIndicies.push_back(markIndex);
|
jointMarkIndices.push_back(markIndex);
|
||||||
|
|
||||||
// First insert joints, then the limb node,
|
// First insert joints, then the limb node,
|
||||||
// because the limb node may contains the triangles of other joint becuase of expanding in split
|
// because the limb node may contains the triangles of other joint becuase of expanding in split
|
||||||
|
@ -66,7 +66,7 @@ bool AnimalRigger::collectJontsForChain(int markIndex, std::vector<int> &jointMa
|
||||||
for (const auto &triangle: group) {
|
for (const auto &triangle: group) {
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
int j = (i + 1) % 3;
|
int j = (i + 1) % 3;
|
||||||
edgeToTriangleMap.insert({{triangle.indicies[i], triangle.indicies[j]}, &triangle});
|
edgeToTriangleMap.insert({{triangle.indices[i], triangle.indices[j]}, &triangle});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ bool AnimalRigger::collectJontsForChain(int markIndex, std::vector<int> &jointMa
|
||||||
for (const auto &triangle: mark.markTriangles) {
|
for (const auto &triangle: mark.markTriangles) {
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
int j = (i + 1) % 3;
|
int j = (i + 1) % 3;
|
||||||
auto findOppositeTriangleResult = edgeToTriangleMap.find({triangle.indicies[j], triangle.indicies[i]});
|
auto findOppositeTriangleResult = edgeToTriangleMap.find({triangle.indices[j], triangle.indices[i]});
|
||||||
if (findOppositeTriangleResult == edgeToTriangleMap.end())
|
if (findOppositeTriangleResult == edgeToTriangleMap.end())
|
||||||
continue;
|
continue;
|
||||||
const MeshSplitterTriangle *startupTriangle = findOppositeTriangleResult->second;
|
const MeshSplitterTriangle *startupTriangle = findOppositeTriangleResult->second;
|
||||||
|
@ -106,7 +106,7 @@ bool AnimalRigger::collectJontsForChain(int markIndex, std::vector<int> &jointMa
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
int j = (i + 1) % 3;
|
int j = (i + 1) % 3;
|
||||||
auto findOppositeTriangleResult = edgeToTriangleMap.find({triangle->indicies[j], triangle->indicies[i]});
|
auto findOppositeTriangleResult = edgeToTriangleMap.find({triangle->indices[j], triangle->indices[i]});
|
||||||
if (findOppositeTriangleResult == edgeToTriangleMap.end())
|
if (findOppositeTriangleResult == edgeToTriangleMap.end())
|
||||||
continue;
|
continue;
|
||||||
const MeshSplitterTriangle *neighborTriangle = findOppositeTriangleResult->second;
|
const MeshSplitterTriangle *neighborTriangle = findOppositeTriangleResult->second;
|
||||||
|
@ -166,7 +166,7 @@ bool AnimalRigger::collectJontsForChain(int markIndex, std::vector<int> &jointMa
|
||||||
qDebug() << "Find nearest joint failed";
|
qDebug() << "Find nearest joint failed";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
jointMarkIndicies.push_back(nearestMarkIndex);
|
jointMarkIndices.push_back(nearestMarkIndex);
|
||||||
visited.insert(nearestMarkIndex);
|
visited.insert(nearestMarkIndex);
|
||||||
findPairResult = pairs.find(nearestMarkIndex);
|
findPairResult = pairs.find(nearestMarkIndex);
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,7 @@ bool AnimalRigger::collectJontsForChain(int markIndex, std::vector<int> &jointMa
|
||||||
linkTo = item;
|
linkTo = item;
|
||||||
//qDebug() << "Link" << findPairResult->first << "to" << linkTo;
|
//qDebug() << "Link" << findPairResult->first << "to" << linkTo;
|
||||||
visited.insert(linkTo);
|
visited.insert(linkTo);
|
||||||
jointMarkIndicies.push_back(linkTo);
|
jointMarkIndices.push_back(linkTo);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (-1 == linkTo)
|
if (-1 == linkTo)
|
||||||
|
@ -210,43 +210,43 @@ bool AnimalRigger::rig()
|
||||||
qDebug() << "isMainBodyVerticalAligned:" << isMainBodyVerticalAligned;
|
qDebug() << "isMainBodyVerticalAligned:" << isMainBodyVerticalAligned;
|
||||||
|
|
||||||
// Collect all branchs
|
// Collect all branchs
|
||||||
auto neckIndicies = m_marksMap.find(std::make_pair(BoneMark::Neck, SkeletonSide::None));
|
auto neckIndices = m_marksMap.find(std::make_pair(BoneMark::Neck, SkeletonSide::None));
|
||||||
auto tailIndicies = m_marksMap.find(std::make_pair(BoneMark::Tail, SkeletonSide::None));
|
auto tailIndices = m_marksMap.find(std::make_pair(BoneMark::Tail, SkeletonSide::None));
|
||||||
auto leftLimbIndicies = m_marksMap.find(std::make_pair(BoneMark::Limb, SkeletonSide::Left));
|
auto leftLimbIndices = m_marksMap.find(std::make_pair(BoneMark::Limb, SkeletonSide::Left));
|
||||||
auto rightLimbIndicies = m_marksMap.find(std::make_pair(BoneMark::Limb, SkeletonSide::Right));
|
auto rightLimbIndices = m_marksMap.find(std::make_pair(BoneMark::Limb, SkeletonSide::Right));
|
||||||
std::vector<int> nosideMarkIndicies;
|
std::vector<int> nosideMarkIndices;
|
||||||
std::vector<int> leftMarkIndicies;
|
std::vector<int> leftMarkIndices;
|
||||||
std::vector<int> righMarkIndicies;
|
std::vector<int> righMarkIndices;
|
||||||
if (neckIndicies != m_marksMap.end()) {
|
if (neckIndices != m_marksMap.end()) {
|
||||||
for (const auto &index: neckIndicies->second)
|
for (const auto &index: neckIndices->second)
|
||||||
nosideMarkIndicies.push_back(index);
|
nosideMarkIndices.push_back(index);
|
||||||
}
|
}
|
||||||
if (tailIndicies != m_marksMap.end()) {
|
if (tailIndices != m_marksMap.end()) {
|
||||||
for (const auto &index: tailIndicies->second)
|
for (const auto &index: tailIndices->second)
|
||||||
nosideMarkIndicies.push_back(index);
|
nosideMarkIndices.push_back(index);
|
||||||
}
|
}
|
||||||
if (leftLimbIndicies != m_marksMap.end()) {
|
if (leftLimbIndices != m_marksMap.end()) {
|
||||||
for (const auto &index: leftLimbIndicies->second)
|
for (const auto &index: leftLimbIndices->second)
|
||||||
leftMarkIndicies.push_back(index);
|
leftMarkIndices.push_back(index);
|
||||||
}
|
}
|
||||||
if (rightLimbIndicies != m_marksMap.end()) {
|
if (rightLimbIndices != m_marksMap.end()) {
|
||||||
for (const auto &index: rightLimbIndicies->second)
|
for (const auto &index: rightLimbIndices->second)
|
||||||
righMarkIndicies.push_back(index);
|
righMarkIndices.push_back(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate spine for main body
|
// Generate spine for main body
|
||||||
auto sortMarkIndiciesInSpineOrder = [=](const int &first, const int &second) {
|
auto sortMarkIndicesInSpineOrder = [=](const int &first, const int &second) {
|
||||||
return isMainBodyVerticalAligned ?
|
return isMainBodyVerticalAligned ?
|
||||||
(m_marks[first].bonePosition.y() < m_marks[second].bonePosition.y()) :
|
(m_marks[first].bonePosition.y() < m_marks[second].bonePosition.y()) :
|
||||||
(m_marks[first].bonePosition.z() < m_marks[second].bonePosition.z());
|
(m_marks[first].bonePosition.z() < m_marks[second].bonePosition.z());
|
||||||
};
|
};
|
||||||
std::sort(nosideMarkIndicies.begin(), nosideMarkIndicies.end(), sortMarkIndiciesInSpineOrder);
|
std::sort(nosideMarkIndices.begin(), nosideMarkIndices.end(), sortMarkIndicesInSpineOrder);
|
||||||
std::sort(leftMarkIndicies.begin(), leftMarkIndicies.end(), sortMarkIndiciesInSpineOrder);
|
std::sort(leftMarkIndices.begin(), leftMarkIndices.end(), sortMarkIndicesInSpineOrder);
|
||||||
std::sort(righMarkIndicies.begin(), righMarkIndicies.end(), sortMarkIndiciesInSpineOrder);
|
std::sort(righMarkIndices.begin(), righMarkIndices.end(), sortMarkIndicesInSpineOrder);
|
||||||
const static std::vector<int> s_empty;
|
const static std::vector<int> s_empty;
|
||||||
const std::vector<int> *chainColumns[3] = {&leftMarkIndicies,
|
const std::vector<int> *chainColumns[3] = {&leftMarkIndices,
|
||||||
&nosideMarkIndicies,
|
&nosideMarkIndices,
|
||||||
&righMarkIndicies
|
&righMarkIndices
|
||||||
};
|
};
|
||||||
enum Column
|
enum Column
|
||||||
{
|
{
|
||||||
|
@ -258,18 +258,18 @@ bool AnimalRigger::rig()
|
||||||
{
|
{
|
||||||
float coord;
|
float coord;
|
||||||
QVector3D position;
|
QVector3D position;
|
||||||
std::set<int> chainMarkIndicies;
|
std::set<int> chainMarkIndices;
|
||||||
};
|
};
|
||||||
std::vector<SpineNode> rawSpineNodes;
|
std::vector<SpineNode> rawSpineNodes;
|
||||||
for (size_t sideIndicies[3] = {0, 0, 0};
|
for (size_t sideIndices[3] = {0, 0, 0};
|
||||||
sideIndicies[Column::Noside] < chainColumns[Column::Noside]->size() ||
|
sideIndices[Column::Noside] < chainColumns[Column::Noside]->size() ||
|
||||||
sideIndicies[Column::Left] < chainColumns[Column::Left]->size() ||
|
sideIndices[Column::Left] < chainColumns[Column::Left]->size() ||
|
||||||
sideIndicies[Column::Right] < chainColumns[Column::Right]->size();) {
|
sideIndices[Column::Right] < chainColumns[Column::Right]->size();) {
|
||||||
float choosenCoord = std::numeric_limits<float>::max();
|
float choosenCoord = std::numeric_limits<float>::max();
|
||||||
int choosenColumn = -1;
|
int choosenColumn = -1;
|
||||||
for (size_t side = Column::Left; side <= Column::Right; ++side) {
|
for (size_t side = Column::Left; side <= Column::Right; ++side) {
|
||||||
if (sideIndicies[side] < chainColumns[side]->size()) {
|
if (sideIndices[side] < chainColumns[side]->size()) {
|
||||||
const auto &mark = m_marks[chainColumns[side]->at(sideIndicies[side])];
|
const auto &mark = m_marks[chainColumns[side]->at(sideIndices[side])];
|
||||||
const auto &coord = isMainBodyVerticalAligned ? mark.bonePosition.y() :
|
const auto &coord = isMainBodyVerticalAligned ? mark.bonePosition.y() :
|
||||||
mark.bonePosition.z();
|
mark.bonePosition.z();
|
||||||
if (coord < choosenCoord) {
|
if (coord < choosenCoord) {
|
||||||
|
@ -285,17 +285,17 @@ bool AnimalRigger::rig()
|
||||||
// Find all the chains before or near this choosenCoord
|
// Find all the chains before or near this choosenCoord
|
||||||
QVector3D sumOfChainPositions;
|
QVector3D sumOfChainPositions;
|
||||||
int countOfChains = 0;
|
int countOfChains = 0;
|
||||||
std::set<int> chainMarkIndicies;
|
std::set<int> chainMarkIndices;
|
||||||
for (size_t side = Column::Left; side <= Column::Right; ++side) {
|
for (size_t side = Column::Left; side <= Column::Right; ++side) {
|
||||||
if (sideIndicies[side] < chainColumns[side]->size()) {
|
if (sideIndices[side] < chainColumns[side]->size()) {
|
||||||
const auto &mark = m_marks[chainColumns[side]->at(sideIndicies[side])];
|
const auto &mark = m_marks[chainColumns[side]->at(sideIndices[side])];
|
||||||
const auto &coord = isMainBodyVerticalAligned ? mark.bonePosition.y() :
|
const auto &coord = isMainBodyVerticalAligned ? mark.bonePosition.y() :
|
||||||
mark.bonePosition.z();
|
mark.bonePosition.z();
|
||||||
if (coord <= choosenCoord + 0.001) {
|
if (coord <= choosenCoord + 0.001) {
|
||||||
chainMarkIndicies.insert(chainColumns[side]->at(sideIndicies[side]));
|
chainMarkIndices.insert(chainColumns[side]->at(sideIndices[side]));
|
||||||
sumOfChainPositions += mark.bonePosition;
|
sumOfChainPositions += mark.bonePosition;
|
||||||
++countOfChains;
|
++countOfChains;
|
||||||
++sideIndicies[side];
|
++sideIndices[side];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -307,7 +307,7 @@ bool AnimalRigger::rig()
|
||||||
rawSpineNodes.push_back(SpineNode());
|
rawSpineNodes.push_back(SpineNode());
|
||||||
SpineNode &spineNode = rawSpineNodes.back();
|
SpineNode &spineNode = rawSpineNodes.back();
|
||||||
spineNode.coord = choosenCoord;
|
spineNode.coord = choosenCoord;
|
||||||
spineNode.chainMarkIndicies = chainMarkIndicies;
|
spineNode.chainMarkIndices = chainMarkIndices;
|
||||||
spineNode.position = sumOfChainPositions / countOfChains;
|
spineNode.position = sumOfChainPositions / countOfChains;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,19 +329,19 @@ bool AnimalRigger::rig()
|
||||||
spineNodes.push_back(intermediate);
|
spineNodes.push_back(intermediate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Move the chain mark indicies to the new generated intermediate spine
|
// Move the chain mark indices to the new generated intermediate spine
|
||||||
for (size_t i = 2; i < spineNodes.size(); i += 2) {
|
for (size_t i = 2; i < spineNodes.size(); i += 2) {
|
||||||
auto &spineNode = spineNodes[i];
|
auto &spineNode = spineNodes[i];
|
||||||
std::vector<int> needMoveIndicies;
|
std::vector<int> needMoveIndices;
|
||||||
for (const auto &markIndex: spineNode.chainMarkIndicies) {
|
for (const auto &markIndex: spineNode.chainMarkIndices) {
|
||||||
const auto &chain = m_marks[markIndex];
|
const auto &chain = m_marks[markIndex];
|
||||||
if (chain.boneSide != SkeletonSide::None)
|
if (chain.boneSide != SkeletonSide::None)
|
||||||
needMoveIndicies.push_back(markIndex);
|
needMoveIndices.push_back(markIndex);
|
||||||
}
|
}
|
||||||
auto &previousSpineNode = spineNodes[i - 1];
|
auto &previousSpineNode = spineNodes[i - 1];
|
||||||
for (const auto &markIndex: needMoveIndicies) {
|
for (const auto &markIndex: needMoveIndices) {
|
||||||
previousSpineNode.chainMarkIndicies.insert(markIndex);
|
previousSpineNode.chainMarkIndices.insert(markIndex);
|
||||||
spineNode.chainMarkIndicies.erase(markIndex);
|
spineNode.chainMarkIndices.erase(markIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,12 +438,12 @@ bool AnimalRigger::rig()
|
||||||
m_resultBones[boneIndexMap[namingSpine(spineGenerateOrder - 1)]].children.push_back(spineBone.index);
|
m_resultBones[boneIndexMap[namingSpine(spineGenerateOrder - 1)]].children.push_back(spineBone.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &chainMarkIndex: spineNode.chainMarkIndicies) {
|
for (const auto &chainMarkIndex: spineNode.chainMarkIndices) {
|
||||||
const auto &chainMark = m_marks[chainMarkIndex];
|
const auto &chainMark = m_marks[chainMarkIndex];
|
||||||
|
|
||||||
QString chainBaseName = BoneMarkToString(chainMark.boneMark);
|
QString chainBaseName = BoneMarkToString(chainMark.boneMark);
|
||||||
int chainGenerateOrder = ++chainOrderMapBySide[{chainBaseName, chainMark.boneSide}];
|
int chainGenerateOrder = ++chainOrderMapBySide[{chainBaseName, chainMark.boneSide}];
|
||||||
QString chainName = namingChainPrefix(chainBaseName, chainMark.boneSide, chainGenerateOrder, spineNode.chainMarkIndicies.size());
|
QString chainName = namingChainPrefix(chainBaseName, chainMark.boneSide, chainGenerateOrder, spineNode.chainMarkIndices.size());
|
||||||
|
|
||||||
m_resultBones.push_back(RiggerBone());
|
m_resultBones.push_back(RiggerBone());
|
||||||
RiggerBone &ribBone = m_resultBones.back();
|
RiggerBone &ribBone = m_resultBones.back();
|
||||||
|
@ -458,12 +458,12 @@ bool AnimalRigger::rig()
|
||||||
m_resultBones[boneIndexMap[namingSpine(spineGenerateOrder)]].children.push_back(ribBone.index);
|
m_resultBones[boneIndexMap[namingSpine(spineGenerateOrder)]].children.push_back(ribBone.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int> jointMarkIndicies;
|
std::vector<int> jointMarkIndices;
|
||||||
if (!collectJontsForChain(chainMarkIndex, jointMarkIndicies)) {
|
if (!collectJontsForChain(chainMarkIndex, jointMarkIndices)) {
|
||||||
m_jointErrorItems.push_back(chainName);
|
m_jointErrorItems.push_back(chainName);
|
||||||
}
|
}
|
||||||
|
|
||||||
//qDebug() << "Adding chain:" << chainName << " joints:" << jointMarkIndicies.size();
|
//qDebug() << "Adding chain:" << chainName << " joints:" << jointMarkIndices.size();
|
||||||
|
|
||||||
int jointGenerateOrder = 1;
|
int jointGenerateOrder = 1;
|
||||||
|
|
||||||
|
@ -475,7 +475,7 @@ bool AnimalRigger::rig()
|
||||||
m_resultBones[boneIndexMap[namingConnector(spineName, chainName)]].tailPosition = headPosition;
|
m_resultBones[boneIndexMap[namingConnector(spineName, chainName)]].tailPosition = headPosition;
|
||||||
m_resultBones[boneIndexMap[namingConnector(spineName, chainName)]].children.push_back(boneIndex);
|
m_resultBones[boneIndexMap[namingConnector(spineName, chainName)]].children.push_back(boneIndex);
|
||||||
} else {
|
} else {
|
||||||
QString parentLimbBoneName = namingChain(chainBaseName, side, chainGenerateOrder, spineNode.chainMarkIndicies.size(), jointGenerateOrder - 1);
|
QString parentLimbBoneName = namingChain(chainBaseName, side, chainGenerateOrder, spineNode.chainMarkIndices.size(), jointGenerateOrder - 1);
|
||||||
m_resultBones[boneIndexMap[parentLimbBoneName]].tailPosition = headPosition;
|
m_resultBones[boneIndexMap[parentLimbBoneName]].tailPosition = headPosition;
|
||||||
m_resultBones[boneIndexMap[parentLimbBoneName]].children.push_back(boneIndex);
|
m_resultBones[boneIndexMap[parentLimbBoneName]].children.push_back(boneIndex);
|
||||||
}
|
}
|
||||||
|
@ -486,8 +486,8 @@ bool AnimalRigger::rig()
|
||||||
addTrianglesToVertices(chainMark.markTriangles, remainingLimbVertices);
|
addTrianglesToVertices(chainMark.markTriangles, remainingLimbVertices);
|
||||||
|
|
||||||
std::vector<QVector3D> jointPositions;
|
std::vector<QVector3D> jointPositions;
|
||||||
for (jointGenerateOrder = 1; jointGenerateOrder <= (int)jointMarkIndicies.size(); ++jointGenerateOrder) {
|
for (jointGenerateOrder = 1; jointGenerateOrder <= (int)jointMarkIndices.size(); ++jointGenerateOrder) {
|
||||||
int jointMarkIndex = jointMarkIndicies[jointGenerateOrder - 1];
|
int jointMarkIndex = jointMarkIndices[jointGenerateOrder - 1];
|
||||||
const auto jointMark = m_marks[jointMarkIndex];
|
const auto jointMark = m_marks[jointMarkIndex];
|
||||||
jointPositions.push_back(jointMark.bonePosition);
|
jointPositions.push_back(jointMark.bonePosition);
|
||||||
}
|
}
|
||||||
|
@ -510,21 +510,21 @@ bool AnimalRigger::rig()
|
||||||
// Calculate the tail position from remaining verticies
|
// Calculate the tail position from remaining verticies
|
||||||
jointPositions.push_back(findExtremPointFrom(lastJointBoneVerticies, jointPositions.back()));
|
jointPositions.push_back(findExtremPointFrom(lastJointBoneVerticies, jointPositions.back()));
|
||||||
|
|
||||||
for (jointGenerateOrder = 1; jointGenerateOrder <= (int)jointMarkIndicies.size(); ++jointGenerateOrder) {
|
for (jointGenerateOrder = 1; jointGenerateOrder <= (int)jointMarkIndices.size(); ++jointGenerateOrder) {
|
||||||
int jointMarkIndex = jointMarkIndicies[jointGenerateOrder - 1];
|
int jointMarkIndex = jointMarkIndices[jointGenerateOrder - 1];
|
||||||
const auto &jointMark = m_marks[jointMarkIndex];
|
const auto &jointMark = m_marks[jointMarkIndex];
|
||||||
m_resultBones.push_back(RiggerBone());
|
m_resultBones.push_back(RiggerBone());
|
||||||
RiggerBone &jointBone = m_resultBones.back();
|
RiggerBone &jointBone = m_resultBones.back();
|
||||||
jointBone.index = m_resultBones.size() - 1;
|
jointBone.index = m_resultBones.size() - 1;
|
||||||
jointBone.name = namingChain(chainBaseName, chainMark.boneSide, chainGenerateOrder, spineNode.chainMarkIndicies.size(), jointGenerateOrder);
|
jointBone.name = namingChain(chainBaseName, chainMark.boneSide, chainGenerateOrder, spineNode.chainMarkIndices.size(), jointGenerateOrder);
|
||||||
jointBone.headPosition = jointPositions[jointGenerateOrder - 1];
|
jointBone.headPosition = jointPositions[jointGenerateOrder - 1];
|
||||||
jointBone.tailPosition = jointPositions[jointGenerateOrder];
|
jointBone.tailPosition = jointPositions[jointGenerateOrder];
|
||||||
jointBone.baseNormal = jointMark.baseNormal;
|
jointBone.baseNormal = jointMark.baseNormal;
|
||||||
jointBone.color = boneColor();
|
jointBone.color = boneColor();
|
||||||
if (jointGenerateOrder == (int)jointMarkIndicies.size()) {
|
if (jointGenerateOrder == (int)jointMarkIndices.size()) {
|
||||||
addVerticesToWeights(remainingLimbVertices, jointBone.index);
|
addVerticesToWeights(remainingLimbVertices, jointBone.index);
|
||||||
} else {
|
} else {
|
||||||
int nextJointMarkIndex = jointMarkIndicies[jointGenerateOrder];
|
int nextJointMarkIndex = jointMarkIndices[jointGenerateOrder];
|
||||||
const auto &nextJointMark = m_marks[nextJointMarkIndex];
|
const auto &nextJointMark = m_marks[nextJointMarkIndex];
|
||||||
auto nextBoneDirection = (jointPositions[jointGenerateOrder + 1] - jointPositions[jointGenerateOrder]).normalized();
|
auto nextBoneDirection = (jointPositions[jointGenerateOrder + 1] - jointPositions[jointGenerateOrder]).normalized();
|
||||||
auto currentBoneDirection = (jointBone.tailPosition - jointBone.headPosition).normalized();
|
auto currentBoneDirection = (jointBone.tailPosition - jointBone.headPosition).normalized();
|
||||||
|
|
|
@ -18,7 +18,7 @@ protected:
|
||||||
bool rig() override;
|
bool rig() override;
|
||||||
BoneMark translateBoneMark(BoneMark boneMark) override;
|
BoneMark translateBoneMark(BoneMark boneMark) override;
|
||||||
private:
|
private:
|
||||||
bool collectJontsForChain(int markIndex, std::vector<int> &jointMarkIndicies);
|
bool collectJontsForChain(int markIndex, std::vector<int> &jointMarkIndices);
|
||||||
static QString namingSpine(int spineOrder);
|
static QString namingSpine(int spineOrder);
|
||||||
static QString namingConnector(const QString &spineName, const QString &chainName);
|
static QString namingConnector(const QString &spineName, const QString &chainName);
|
||||||
static QString namingChain(const QString &baseName, SkeletonSide side, int orderInSide, int totalInSide, int jointOrder);
|
static QString namingChain(const QString &baseName, SkeletonSide side, int orderInSide, int totalInSide, int jointOrder);
|
||||||
|
|
|
@ -1703,11 +1703,11 @@ FbxFileWriter::FbxFileWriter(Outcome &outcome,
|
||||||
positions.push_back((double)vertex.y());
|
positions.push_back((double)vertex.y());
|
||||||
positions.push_back((double)vertex.z());
|
positions.push_back((double)vertex.z());
|
||||||
}
|
}
|
||||||
std::vector<int32_t> indicies;
|
std::vector<int32_t> indices;
|
||||||
for (const auto &triangle: outcome.triangles) {
|
for (const auto &triangle: outcome.triangles) {
|
||||||
indicies.push_back(triangle[0]);
|
indices.push_back(triangle[0]);
|
||||||
indicies.push_back(triangle[1]);
|
indices.push_back(triangle[1]);
|
||||||
indicies.push_back(triangle[2] ^ -1);
|
indices.push_back(triangle[2] ^ -1);
|
||||||
}
|
}
|
||||||
FBXNode layerElementNormal("LayerElementNormal");
|
FBXNode layerElementNormal("LayerElementNormal");
|
||||||
const auto triangleVertexNormals = outcome.triangleVertexNormals();
|
const auto triangleVertexNormals = outcome.triangleVertexNormals();
|
||||||
|
@ -1758,7 +1758,7 @@ FbxFileWriter::FbxFileWriter(Outcome &outcome,
|
||||||
layer.addChild(FBXNode());
|
layer.addChild(FBXNode());
|
||||||
geometry.addPropertyNode("GeometryVersion", (int32_t)124);
|
geometry.addPropertyNode("GeometryVersion", (int32_t)124);
|
||||||
geometry.addPropertyNode("Vertices", positions);
|
geometry.addPropertyNode("Vertices", positions);
|
||||||
geometry.addPropertyNode("PolygonVertexIndex", indicies);
|
geometry.addPropertyNode("PolygonVertexIndex", indices);
|
||||||
if (nullptr != triangleVertexNormals)
|
if (nullptr != triangleVertexNormals)
|
||||||
geometry.addChild(layerElementNormal);
|
geometry.addChild(layerElementNormal);
|
||||||
geometry.addChild(layerElementMaterial);
|
geometry.addChild(layerElementMaterial);
|
||||||
|
@ -1837,7 +1837,7 @@ FbxFileWriter::FbxFileWriter(Outcome &outcome,
|
||||||
if (resultRigWeights && !resultRigWeights->empty()) {
|
if (resultRigWeights && !resultRigWeights->empty()) {
|
||||||
for (const auto &item: *resultRigWeights) {
|
for (const auto &item: *resultRigWeights) {
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
const auto &boneIndex = item.second.boneIndicies[i];
|
const auto &boneIndex = item.second.boneIndices[i];
|
||||||
Q_ASSERT(boneIndex < bindPerBone.size());
|
Q_ASSERT(boneIndex < bindPerBone.size());
|
||||||
if (0 == boneIndex)
|
if (0 == boneIndex)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -140,11 +140,11 @@ GlbFileWriter::GlbFileWriter(Outcome &outcome,
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<QVector3D> triangleVertexPositions;
|
std::vector<QVector3D> triangleVertexPositions;
|
||||||
std::vector<size_t> triangleVertexOldIndicies;
|
std::vector<size_t> triangleVertexOldIndices;
|
||||||
for (const auto &triangleIndicies: outcome.triangles) {
|
for (const auto &triangleIndices: outcome.triangles) {
|
||||||
for (size_t j = 0; j < 3; ++j) {
|
for (size_t j = 0; j < 3; ++j) {
|
||||||
triangleVertexOldIndicies.push_back(triangleIndicies[j]);
|
triangleVertexOldIndices.push_back(triangleIndices[j]);
|
||||||
triangleVertexPositions.push_back(outcome.vertices[triangleIndicies[j]]);
|
triangleVertexPositions.push_back(outcome.vertices[triangleIndices[j]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ GlbFileWriter::GlbFileWriter(Outcome &outcome,
|
||||||
Q_ASSERT((int)triangleVertexPositions.size() * sizeof(quint16) == m_binByteArray.size() - bufferViewFromOffset);
|
Q_ASSERT((int)triangleVertexPositions.size() * sizeof(quint16) == m_binByteArray.size() - bufferViewFromOffset);
|
||||||
alignBin();
|
alignBin();
|
||||||
if (m_enableComment)
|
if (m_enableComment)
|
||||||
m_json["accessors"][bufferViewIndex]["__comment"] = QString("/accessors/%1: triangle indicies").arg(QString::number(bufferViewIndex)).toUtf8().constData();
|
m_json["accessors"][bufferViewIndex]["__comment"] = QString("/accessors/%1: triangle indices").arg(QString::number(bufferViewIndex)).toUtf8().constData();
|
||||||
m_json["accessors"][bufferViewIndex]["bufferView"] = bufferViewIndex;
|
m_json["accessors"][bufferViewIndex]["bufferView"] = bufferViewIndex;
|
||||||
m_json["accessors"][bufferViewIndex]["byteOffset"] = 0;
|
m_json["accessors"][bufferViewIndex]["byteOffset"] = 0;
|
||||||
m_json["accessors"][bufferViewIndex]["componentType"] = 5123;
|
m_json["accessors"][bufferViewIndex]["componentType"] = 5123;
|
||||||
|
@ -279,14 +279,14 @@ GlbFileWriter::GlbFileWriter(Outcome &outcome,
|
||||||
m_json["bufferViews"][bufferViewIndex]["byteOffset"] = bufferViewFromOffset;
|
m_json["bufferViews"][bufferViewIndex]["byteOffset"] = bufferViewFromOffset;
|
||||||
QStringList boneList;
|
QStringList boneList;
|
||||||
int weightItIndex = 0;
|
int weightItIndex = 0;
|
||||||
for (const auto &oldIndex: triangleVertexOldIndicies) {
|
for (const auto &oldIndex: triangleVertexOldIndices) {
|
||||||
auto i = 0u;
|
auto i = 0u;
|
||||||
if (m_enableComment)
|
if (m_enableComment)
|
||||||
boneList.append(QString("%1:<").arg(QString::number(weightItIndex)));
|
boneList.append(QString("%1:<").arg(QString::number(weightItIndex)));
|
||||||
auto findWeight = resultRigWeights->find(oldIndex);
|
auto findWeight = resultRigWeights->find(oldIndex);
|
||||||
if (findWeight != resultRigWeights->end()) {
|
if (findWeight != resultRigWeights->end()) {
|
||||||
for (; i < MAX_WEIGHT_NUM; i++) {
|
for (; i < MAX_WEIGHT_NUM; i++) {
|
||||||
quint16 nodeIndex = (quint16)findWeight->second.boneIndicies[i];
|
quint16 nodeIndex = (quint16)findWeight->second.boneIndices[i];
|
||||||
binStream << (quint16)nodeIndex;
|
binStream << (quint16)nodeIndex;
|
||||||
if (m_enableComment)
|
if (m_enableComment)
|
||||||
boneList.append(QString("%1").arg(nodeIndex));
|
boneList.append(QString("%1").arg(nodeIndex));
|
||||||
|
@ -304,11 +304,11 @@ GlbFileWriter::GlbFileWriter(Outcome &outcome,
|
||||||
m_json["bufferViews"][bufferViewIndex]["byteLength"] = m_binByteArray.size() - bufferViewFromOffset;
|
m_json["bufferViews"][bufferViewIndex]["byteLength"] = m_binByteArray.size() - bufferViewFromOffset;
|
||||||
alignBin();
|
alignBin();
|
||||||
if (m_enableComment)
|
if (m_enableComment)
|
||||||
m_json["accessors"][bufferViewIndex]["__comment"] = QString("/accessors/%1: bone indicies %2").arg(QString::number(bufferViewIndex)).arg(boneList.join(" ")).toUtf8().constData();
|
m_json["accessors"][bufferViewIndex]["__comment"] = QString("/accessors/%1: bone indices %2").arg(QString::number(bufferViewIndex)).arg(boneList.join(" ")).toUtf8().constData();
|
||||||
m_json["accessors"][bufferViewIndex]["bufferView"] = bufferViewIndex;
|
m_json["accessors"][bufferViewIndex]["bufferView"] = bufferViewIndex;
|
||||||
m_json["accessors"][bufferViewIndex]["byteOffset"] = 0;
|
m_json["accessors"][bufferViewIndex]["byteOffset"] = 0;
|
||||||
m_json["accessors"][bufferViewIndex]["componentType"] = 5123;
|
m_json["accessors"][bufferViewIndex]["componentType"] = 5123;
|
||||||
m_json["accessors"][bufferViewIndex]["count"] = triangleVertexOldIndicies.size();
|
m_json["accessors"][bufferViewIndex]["count"] = triangleVertexOldIndices.size();
|
||||||
m_json["accessors"][bufferViewIndex]["type"] = "VEC4";
|
m_json["accessors"][bufferViewIndex]["type"] = "VEC4";
|
||||||
bufferViewIndex++;
|
bufferViewIndex++;
|
||||||
|
|
||||||
|
@ -317,7 +317,7 @@ GlbFileWriter::GlbFileWriter(Outcome &outcome,
|
||||||
m_json["bufferViews"][bufferViewIndex]["byteOffset"] = bufferViewFromOffset;
|
m_json["bufferViews"][bufferViewIndex]["byteOffset"] = bufferViewFromOffset;
|
||||||
QStringList weightList;
|
QStringList weightList;
|
||||||
weightItIndex = 0;
|
weightItIndex = 0;
|
||||||
for (const auto &oldIndex: triangleVertexOldIndicies) {
|
for (const auto &oldIndex: triangleVertexOldIndices) {
|
||||||
auto i = 0u;
|
auto i = 0u;
|
||||||
if (m_enableComment)
|
if (m_enableComment)
|
||||||
weightList.append(QString("%1:<").arg(QString::number(weightItIndex)));
|
weightList.append(QString("%1:<").arg(QString::number(weightItIndex)));
|
||||||
|
@ -346,7 +346,7 @@ GlbFileWriter::GlbFileWriter(Outcome &outcome,
|
||||||
m_json["accessors"][bufferViewIndex]["bufferView"] = bufferViewIndex;
|
m_json["accessors"][bufferViewIndex]["bufferView"] = bufferViewIndex;
|
||||||
m_json["accessors"][bufferViewIndex]["byteOffset"] = 0;
|
m_json["accessors"][bufferViewIndex]["byteOffset"] = 0;
|
||||||
m_json["accessors"][bufferViewIndex]["componentType"] = 5126;
|
m_json["accessors"][bufferViewIndex]["componentType"] = 5126;
|
||||||
m_json["accessors"][bufferViewIndex]["count"] = triangleVertexOldIndicies.size();
|
m_json["accessors"][bufferViewIndex]["count"] = triangleVertexOldIndices.size();
|
||||||
m_json["accessors"][bufferViewIndex]["type"] = "VEC4";
|
m_json["accessors"][bufferViewIndex]["type"] = "VEC4";
|
||||||
bufferViewIndex++;
|
bufferViewIndex++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,13 +186,13 @@ void MeshGenerator::loadGeneratedPositionsToOutcome(void *meshliteContext, int t
|
||||||
for (int i = 0, triangleVertIndex = 0, normalIndex=0;
|
for (int i = 0, triangleVertIndex = 0, normalIndex=0;
|
||||||
i < triangleCount;
|
i < triangleCount;
|
||||||
i++, triangleVertIndex+=3, normalIndex += 3) {
|
i++, triangleVertIndex+=3, normalIndex += 3) {
|
||||||
std::vector<size_t> triangleIndicies(3);
|
std::vector<size_t> triangleIndices(3);
|
||||||
QVector3D triangleNormal;
|
QVector3D triangleNormal;
|
||||||
triangleIndicies[0] = verticesMap[triangleIndexBuffer[triangleVertIndex + 0]];
|
triangleIndices[0] = verticesMap[triangleIndexBuffer[triangleVertIndex + 0]];
|
||||||
triangleIndicies[1] = verticesMap[triangleIndexBuffer[triangleVertIndex + 1]];
|
triangleIndices[1] = verticesMap[triangleIndexBuffer[triangleVertIndex + 1]];
|
||||||
triangleIndicies[2] = verticesMap[triangleIndexBuffer[triangleVertIndex + 2]];
|
triangleIndices[2] = verticesMap[triangleIndexBuffer[triangleVertIndex + 2]];
|
||||||
triangleNormal = QVector3D(normalBuffer[normalIndex + 0], normalBuffer[normalIndex + 1], normalBuffer[normalIndex + 2]);
|
triangleNormal = QVector3D(normalBuffer[normalIndex + 0], normalBuffer[normalIndex + 1], normalBuffer[normalIndex + 2]);
|
||||||
m_outcome->triangles.push_back(triangleIndicies);
|
m_outcome->triangles.push_back(triangleIndices);
|
||||||
m_outcome->triangleNormals.push_back(triangleNormal);
|
m_outcome->triangleNormals.push_back(triangleNormal);
|
||||||
}
|
}
|
||||||
delete[] positionBuffer;
|
delete[] positionBuffer;
|
||||||
|
@ -642,14 +642,14 @@ void *MeshGenerator::combineComponentMesh(QString componentId, CombineMode *comb
|
||||||
|
|
||||||
if (!positionsBeforeSmooth.empty()) {
|
if (!positionsBeforeSmooth.empty()) {
|
||||||
std::vector<int> seamVerticesIds;
|
std::vector<int> seamVerticesIds;
|
||||||
std::unordered_set<int> seamVerticesIndicies;
|
std::unordered_set<int> seamVerticesIndices;
|
||||||
|
|
||||||
if (!positionsBeforeCombination.map().empty()) {
|
if (!positionsBeforeCombination.map().empty()) {
|
||||||
for (size_t vertexIndex = 0; vertexIndex < positionsBeforeSmooth.size(); vertexIndex++) {
|
for (size_t vertexIndex = 0; vertexIndex < positionsBeforeSmooth.size(); vertexIndex++) {
|
||||||
const auto &oldPosition = positionsBeforeSmooth[vertexIndex];
|
const auto &oldPosition = positionsBeforeSmooth[vertexIndex];
|
||||||
if (!positionsBeforeCombination.findPosition(oldPosition.x(), oldPosition.y(), oldPosition.z())) {
|
if (!positionsBeforeCombination.findPosition(oldPosition.x(), oldPosition.y(), oldPosition.z())) {
|
||||||
seamVerticesIds.push_back(vertexIndex + 1);
|
seamVerticesIds.push_back(vertexIndex + 1);
|
||||||
seamVerticesIndicies.insert(vertexIndex);
|
seamVerticesIndices.insert(vertexIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -658,7 +658,7 @@ void *MeshGenerator::combineComponentMesh(QString componentId, CombineMode *comb
|
||||||
|
|
||||||
if (smoothSeam) {
|
if (smoothSeam) {
|
||||||
if (!seamVerticesIds.empty()) {
|
if (!seamVerticesIds.empty()) {
|
||||||
//qDebug() << "smoothSeamFactor:" << smoothSeamFactor << "seamVerticesIndicies.size():" << seamVerticesNum;
|
//qDebug() << "smoothSeamFactor:" << smoothSeamFactor << "seamVerticesIndices.size():" << seamVerticesNum;
|
||||||
meshlite_smooth_vertices(m_meshliteContext, meshIdForSmooth, smoothSeamFactor, seamVerticesIds.data(), seamVerticesIds.size());
|
meshlite_smooth_vertices(m_meshliteContext, meshIdForSmooth, smoothSeamFactor, seamVerticesIds.data(), seamVerticesIds.size());
|
||||||
meshChanged = true;
|
meshChanged = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,7 +145,7 @@ MeshLoader::MeshLoader(void *meshlite, int meshId, int triangulatedMeshId, QColo
|
||||||
assert(firstIndex + j < loadedTriangleVertexIndexItemCount);
|
assert(firstIndex + j < loadedTriangleVertexIndexItemCount);
|
||||||
int posIndex = triangleIndices[firstIndex + j] * 3;
|
int posIndex = triangleIndices[firstIndex + j] * 3;
|
||||||
assert(posIndex < loadedTriangleVertexPositionItemCount);
|
assert(posIndex < loadedTriangleVertexPositionItemCount);
|
||||||
triangulatedFace.indicies[j] = triangleIndices[firstIndex + j];
|
triangulatedFace.indices[j] = triangleIndices[firstIndex + j];
|
||||||
Vertex *v = &m_triangleVertices[firstIndex + j];
|
Vertex *v = &m_triangleVertices[firstIndex + j];
|
||||||
v->posX = triangleVertexPositions[posIndex + 0];
|
v->posX = triangleVertexPositions[posIndex + 0];
|
||||||
v->posY = triangleVertexPositions[posIndex + 1];
|
v->posY = triangleVertexPositions[posIndex + 1];
|
||||||
|
|
|
@ -35,7 +35,7 @@ typedef struct
|
||||||
|
|
||||||
struct TriangulatedFace
|
struct TriangulatedFace
|
||||||
{
|
{
|
||||||
int indicies[3];
|
int indices[3];
|
||||||
QColor color;
|
QColor color;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ int meshQuadify(void *meshlite, int meshId, const std::set<std::pair<PositionMap
|
||||||
int *faceVertexNumAndIndices = new int[faceCount * MAX_VERTICES_PER_FACE];
|
int *faceVertexNumAndIndices = new int[faceCount * MAX_VERTICES_PER_FACE];
|
||||||
int filledLength = meshlite_get_face_index_array(meshlite, meshId, faceVertexNumAndIndices, faceCount * MAX_VERTICES_PER_FACE);
|
int filledLength = meshlite_get_face_index_array(meshlite, meshId, faceVertexNumAndIndices, faceCount * MAX_VERTICES_PER_FACE);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
std::vector<std::vector<int>> newFaceIndicies;
|
std::vector<std::vector<int>> newFaceIndices;
|
||||||
while (i < filledLength) {
|
while (i < filledLength) {
|
||||||
int num = faceVertexNumAndIndices[i++];
|
int num = faceVertexNumAndIndices[i++];
|
||||||
Q_ASSERT(num > 0 && num <= MAX_VERTICES_PER_FACE);
|
Q_ASSERT(num > 0 && num <= MAX_VERTICES_PER_FACE);
|
||||||
|
@ -38,20 +38,20 @@ int meshQuadify(void *meshlite, int meshId, const std::set<std::pair<PositionMap
|
||||||
Q_ASSERT(index >= 0 && index < vertexCount);
|
Q_ASSERT(index >= 0 && index < vertexCount);
|
||||||
indices.push_back(index);
|
indices.push_back(index);
|
||||||
}
|
}
|
||||||
newFaceIndicies.push_back(indices);
|
newFaceIndices.push_back(indices);
|
||||||
}
|
}
|
||||||
int quadMesh = 0;
|
int quadMesh = 0;
|
||||||
std::map<std::pair<int, int>, std::pair<int, int>> triangleEdgeMap;
|
std::map<std::pair<int, int>, std::pair<int, int>> triangleEdgeMap;
|
||||||
for (int i = 0; i < (int)newFaceIndicies.size(); i++) {
|
for (int i = 0; i < (int)newFaceIndices.size(); i++) {
|
||||||
const auto &faceIndicies = newFaceIndicies[i];
|
const auto &faceIndices = newFaceIndices[i];
|
||||||
if (faceIndicies.size() == 3) {
|
if (faceIndices.size() == 3) {
|
||||||
triangleEdgeMap[std::make_pair(faceIndicies[0], faceIndicies[1])] = std::make_pair(i, faceIndicies[2]);
|
triangleEdgeMap[std::make_pair(faceIndices[0], faceIndices[1])] = std::make_pair(i, faceIndices[2]);
|
||||||
triangleEdgeMap[std::make_pair(faceIndicies[1], faceIndicies[2])] = std::make_pair(i, faceIndicies[0]);
|
triangleEdgeMap[std::make_pair(faceIndices[1], faceIndices[2])] = std::make_pair(i, faceIndices[0]);
|
||||||
triangleEdgeMap[std::make_pair(faceIndicies[2], faceIndicies[0])] = std::make_pair(i, faceIndicies[1]);
|
triangleEdgeMap[std::make_pair(faceIndices[2], faceIndices[0])] = std::make_pair(i, faceIndices[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::unordered_set<int> unionedFaces;
|
std::unordered_set<int> unionedFaces;
|
||||||
std::vector<std::vector<int>> newUnionedFaceIndicies;
|
std::vector<std::vector<int>> newUnionedFaceIndices;
|
||||||
for (const auto &edge: triangleEdgeMap) {
|
for (const auto &edge: triangleEdgeMap) {
|
||||||
if (unionedFaces.find(edge.second.first) != unionedFaces.end())
|
if (unionedFaces.find(edge.second.first) != unionedFaces.end())
|
||||||
continue;
|
continue;
|
||||||
|
@ -69,24 +69,24 @@ int meshQuadify(void *meshlite, int meshId, const std::set<std::pair<PositionMap
|
||||||
indices.push_back(edge.first.first);
|
indices.push_back(edge.first.first);
|
||||||
indices.push_back(oppositeEdge->second.second);
|
indices.push_back(oppositeEdge->second.second);
|
||||||
indices.push_back(edge.first.second);
|
indices.push_back(edge.first.second);
|
||||||
newUnionedFaceIndicies.push_back(indices);
|
newUnionedFaceIndices.push_back(indices);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::vector<int> newFaceVertexNumAndIndices;
|
std::vector<int> newFaceVertexNumAndIndices;
|
||||||
for (int i = 0; i < (int)newFaceIndicies.size(); i++) {
|
for (int i = 0; i < (int)newFaceIndices.size(); i++) {
|
||||||
if (unionedFaces.find(i) == unionedFaces.end()) {
|
if (unionedFaces.find(i) == unionedFaces.end()) {
|
||||||
const auto &faceIndicies = newFaceIndicies[i];
|
const auto &faceIndices = newFaceIndices[i];
|
||||||
newFaceVertexNumAndIndices.push_back(faceIndicies.size());
|
newFaceVertexNumAndIndices.push_back(faceIndices.size());
|
||||||
for (const auto &index: faceIndicies) {
|
for (const auto &index: faceIndices) {
|
||||||
newFaceVertexNumAndIndices.push_back(index);
|
newFaceVertexNumAndIndices.push_back(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const auto &faceIndicies: newUnionedFaceIndicies) {
|
for (const auto &faceIndices: newUnionedFaceIndices) {
|
||||||
newFaceVertexNumAndIndices.push_back(faceIndicies.size());
|
newFaceVertexNumAndIndices.push_back(faceIndices.size());
|
||||||
for (const auto &index: faceIndicies) {
|
for (const auto &index: faceIndices) {
|
||||||
newFaceVertexNumAndIndices.push_back(index);
|
newFaceVertexNumAndIndices.push_back(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ bool MeshSplitter::split(const std::set<MeshSplitterTriangle> &input,
|
||||||
for (const auto &triangle: input) {
|
for (const auto &triangle: input) {
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
int next = (i + 1) % 3;
|
int next = (i + 1) % 3;
|
||||||
edgeToTriangleMap[std::make_pair(triangle.indicies[i], triangle.indicies[next])] = triangle;
|
edgeToTriangleMap[std::make_pair(triangle.indices[i], triangle.indices[next])] = triangle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ bool MeshSplitter::split(const std::set<MeshSplitterTriangle> &input,
|
||||||
for (const auto &triangle: splitter) {
|
for (const auto &triangle: splitter) {
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
int next = (i + 1) % 3;
|
int next = (i + 1) % 3;
|
||||||
auto oppositeEdge = std::make_pair(triangle.indicies[next], triangle.indicies[i]);
|
auto oppositeEdge = std::make_pair(triangle.indices[next], triangle.indices[i]);
|
||||||
auto oppositeTriangle = edgeToTriangleMap.find(oppositeEdge);
|
auto oppositeTriangle = edgeToTriangleMap.find(oppositeEdge);
|
||||||
if (oppositeTriangle == edgeToTriangleMap.end()) {
|
if (oppositeTriangle == edgeToTriangleMap.end()) {
|
||||||
qDebug() << "Find opposite edge failed:" << oppositeEdge.first << oppositeEdge.second;
|
qDebug() << "Find opposite edge failed:" << oppositeEdge.first << oppositeEdge.second;
|
||||||
|
@ -57,7 +57,7 @@ bool MeshSplitter::split(const std::set<MeshSplitterTriangle> &input,
|
||||||
for (const auto &triangle: splitter) {
|
for (const auto &triangle: splitter) {
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
int next = (i + 1) % 3;
|
int next = (i + 1) % 3;
|
||||||
auto oppositeEdge = std::make_pair(triangle.indicies[next], triangle.indicies[i]);
|
auto oppositeEdge = std::make_pair(triangle.indices[next], triangle.indices[i]);
|
||||||
auto oppositeTriangle = edgeToTriangleMap.find(oppositeEdge);
|
auto oppositeTriangle = edgeToTriangleMap.find(oppositeEdge);
|
||||||
if (oppositeTriangle == edgeToTriangleMap.end()) {
|
if (oppositeTriangle == edgeToTriangleMap.end()) {
|
||||||
qDebug() << "Find opposite edge failed:" << oppositeEdge.first << oppositeEdge.second;
|
qDebug() << "Find opposite edge failed:" << oppositeEdge.first << oppositeEdge.second;
|
||||||
|
@ -90,7 +90,7 @@ bool MeshSplitter::split(const std::set<MeshSplitterTriangle> &input,
|
||||||
continue;
|
continue;
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
int next = (i + 1) % 3;
|
int next = (i + 1) % 3;
|
||||||
auto oppositeEdge = std::make_pair(triangle.indicies[next], triangle.indicies[i]);
|
auto oppositeEdge = std::make_pair(triangle.indices[next], triangle.indices[i]);
|
||||||
auto oppositeTriangle = edgeToTriangleMap.find(oppositeEdge);
|
auto oppositeTriangle = edgeToTriangleMap.find(oppositeEdge);
|
||||||
if (oppositeTriangle == edgeToTriangleMap.end()) {
|
if (oppositeTriangle == edgeToTriangleMap.end()) {
|
||||||
qDebug() << "Find opposite edge failed:" << oppositeEdge.first << oppositeEdge.second;
|
qDebug() << "Find opposite edge failed:" << oppositeEdge.first << oppositeEdge.second;
|
||||||
|
|
|
@ -5,12 +5,12 @@
|
||||||
class MeshSplitterTriangle
|
class MeshSplitterTriangle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int indicies[3] = {0, 0, 0};
|
int indices[3] = {0, 0, 0};
|
||||||
|
|
||||||
bool operator<(const MeshSplitterTriangle &other) const
|
bool operator<(const MeshSplitterTriangle &other) const
|
||||||
{
|
{
|
||||||
return std::make_tuple(indicies[0], indicies[1], indicies[2]) <
|
return std::make_tuple(indices[0], indices[1], indices[2]) <
|
||||||
std::make_tuple(other.indicies[0], other.indicies[1], other.indicies[2]);
|
std::make_tuple(other.indices[0], other.indices[1], other.indices[2]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ int meshWeldSeam(void *meshlite, int meshId, float allowedSmallestDistance, cons
|
||||||
int *faceVertexNumAndIndices = new int[faceCount * MAX_VERTICES_PER_FACE];
|
int *faceVertexNumAndIndices = new int[faceCount * MAX_VERTICES_PER_FACE];
|
||||||
int filledLength = meshlite_get_face_index_array(meshlite, meshId, faceVertexNumAndIndices, faceCount * MAX_VERTICES_PER_FACE);
|
int filledLength = meshlite_get_face_index_array(meshlite, meshId, faceVertexNumAndIndices, faceCount * MAX_VERTICES_PER_FACE);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
std::vector<std::vector<int>> newFaceIndicies;
|
std::vector<std::vector<int>> newFaceIndices;
|
||||||
while (i < filledLength) {
|
while (i < filledLength) {
|
||||||
int num = faceVertexNumAndIndices[i++];
|
int num = faceVertexNumAndIndices[i++];
|
||||||
Q_ASSERT(num > 0 && num <= MAX_VERTICES_PER_FACE);
|
Q_ASSERT(num > 0 && num <= MAX_VERTICES_PER_FACE);
|
||||||
|
@ -44,7 +44,7 @@ int meshWeldSeam(void *meshlite, int meshId, float allowedSmallestDistance, cons
|
||||||
Q_ASSERT(index >= 0 && index < vertexCount);
|
Q_ASSERT(index >= 0 && index < vertexCount);
|
||||||
indices.push_back(index);
|
indices.push_back(index);
|
||||||
}
|
}
|
||||||
newFaceIndicies.push_back(indices);
|
newFaceIndices.push_back(indices);
|
||||||
}
|
}
|
||||||
float squareOfAllowedSmallestDistance = allowedSmallestDistance * allowedSmallestDistance;
|
float squareOfAllowedSmallestDistance = allowedSmallestDistance * allowedSmallestDistance;
|
||||||
int weldedMesh = 0;
|
int weldedMesh = 0;
|
||||||
|
@ -53,33 +53,33 @@ int meshWeldSeam(void *meshlite, int meshId, float allowedSmallestDistance, cons
|
||||||
std::unordered_set<int> processedFaces;
|
std::unordered_set<int> processedFaces;
|
||||||
std::map<std::pair<int, int>, std::pair<int, int>> triangleEdgeMap;
|
std::map<std::pair<int, int>, std::pair<int, int>> triangleEdgeMap;
|
||||||
std::unordered_map<int, int> vertexAdjFaceCountMap;
|
std::unordered_map<int, int> vertexAdjFaceCountMap;
|
||||||
for (int i = 0; i < (int)newFaceIndicies.size(); i++) {
|
for (int i = 0; i < (int)newFaceIndices.size(); i++) {
|
||||||
const auto &faceIndicies = newFaceIndicies[i];
|
const auto &faceIndices = newFaceIndices[i];
|
||||||
if (faceIndicies.size() == 3) {
|
if (faceIndices.size() == 3) {
|
||||||
vertexAdjFaceCountMap[faceIndicies[0]]++;
|
vertexAdjFaceCountMap[faceIndices[0]]++;
|
||||||
vertexAdjFaceCountMap[faceIndicies[1]]++;
|
vertexAdjFaceCountMap[faceIndices[1]]++;
|
||||||
vertexAdjFaceCountMap[faceIndicies[2]]++;
|
vertexAdjFaceCountMap[faceIndices[2]]++;
|
||||||
triangleEdgeMap[std::make_pair(faceIndicies[0], faceIndicies[1])] = std::make_pair(i, faceIndicies[2]);
|
triangleEdgeMap[std::make_pair(faceIndices[0], faceIndices[1])] = std::make_pair(i, faceIndices[2]);
|
||||||
triangleEdgeMap[std::make_pair(faceIndicies[1], faceIndicies[2])] = std::make_pair(i, faceIndicies[0]);
|
triangleEdgeMap[std::make_pair(faceIndices[1], faceIndices[2])] = std::make_pair(i, faceIndices[0]);
|
||||||
triangleEdgeMap[std::make_pair(faceIndicies[2], faceIndicies[0])] = std::make_pair(i, faceIndicies[1]);
|
triangleEdgeMap[std::make_pair(faceIndices[2], faceIndices[0])] = std::make_pair(i, faceIndices[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < (int)newFaceIndicies.size(); i++) {
|
for (int i = 0; i < (int)newFaceIndices.size(); i++) {
|
||||||
if (processedFaces.find(i) != processedFaces.end())
|
if (processedFaces.find(i) != processedFaces.end())
|
||||||
continue;
|
continue;
|
||||||
const auto &faceIndicies = newFaceIndicies[i];
|
const auto &faceIndices = newFaceIndices[i];
|
||||||
if (faceIndicies.size() == 3) {
|
if (faceIndices.size() == 3) {
|
||||||
bool indiciesSeamCheck[3] = {
|
bool indicesSeamCheck[3] = {
|
||||||
excludeVertices.find(faceIndicies[0]) == excludeVertices.end(),
|
excludeVertices.find(faceIndices[0]) == excludeVertices.end(),
|
||||||
excludeVertices.find(faceIndicies[1]) == excludeVertices.end(),
|
excludeVertices.find(faceIndices[1]) == excludeVertices.end(),
|
||||||
excludeVertices.find(faceIndicies[2]) == excludeVertices.end()
|
excludeVertices.find(faceIndices[2]) == excludeVertices.end()
|
||||||
};
|
};
|
||||||
for (int j = 0; j < 3; j++) {
|
for (int j = 0; j < 3; j++) {
|
||||||
int next = (j + 1) % 3;
|
int next = (j + 1) % 3;
|
||||||
int nextNext = (j + 2) % 3;
|
int nextNext = (j + 2) % 3;
|
||||||
if (indiciesSeamCheck[j] && indiciesSeamCheck[next]) {
|
if (indicesSeamCheck[j] && indicesSeamCheck[next]) {
|
||||||
std::pair<int, int> edge = std::make_pair(faceIndicies[j], faceIndicies[next]);
|
std::pair<int, int> edge = std::make_pair(faceIndices[j], faceIndices[next]);
|
||||||
int thirdVertexIndex = faceIndicies[nextNext];
|
int thirdVertexIndex = faceIndices[nextNext];
|
||||||
if ((positions[edge.first] - positions[edge.second]).lengthSquared() < squareOfAllowedSmallestDistance) {
|
if ((positions[edge.first] - positions[edge.second]).lengthSquared() < squareOfAllowedSmallestDistance) {
|
||||||
auto oppositeEdge = std::make_pair(edge.second, edge.first);
|
auto oppositeEdge = std::make_pair(edge.second, edge.first);
|
||||||
auto findOppositeFace = triangleEdgeMap.find(oppositeEdge);
|
auto findOppositeFace = triangleEdgeMap.find(oppositeEdge);
|
||||||
|
@ -113,11 +113,11 @@ int meshWeldSeam(void *meshlite, int meshId, float allowedSmallestDistance, cons
|
||||||
std::vector<int> newFaceVertexNumAndIndices;
|
std::vector<int> newFaceVertexNumAndIndices;
|
||||||
int weldedCount = 0;
|
int weldedCount = 0;
|
||||||
int faceCountAfterWeld = 0;
|
int faceCountAfterWeld = 0;
|
||||||
for (int i = 0; i < (int)newFaceIndicies.size(); i++) {
|
for (int i = 0; i < (int)newFaceIndices.size(); i++) {
|
||||||
const auto &faceIndicies = newFaceIndicies[i];
|
const auto &faceIndices = newFaceIndices[i];
|
||||||
std::vector<int> mappedFaceIndicies;
|
std::vector<int> mappedFaceIndices;
|
||||||
bool errored = false;
|
bool errored = false;
|
||||||
for (const auto &index: faceIndicies) {
|
for (const auto &index: faceIndices) {
|
||||||
int finalIndex = index;
|
int finalIndex = index;
|
||||||
int mapTimes = 0;
|
int mapTimes = 0;
|
||||||
while (mapTimes < 500) {
|
while (mapTimes < 500) {
|
||||||
|
@ -132,14 +132,14 @@ int meshWeldSeam(void *meshlite, int meshId, float allowedSmallestDistance, cons
|
||||||
errored = true;
|
errored = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mappedFaceIndicies.push_back(finalIndex);
|
mappedFaceIndices.push_back(finalIndex);
|
||||||
}
|
}
|
||||||
if (errored || mappedFaceIndicies.size() < 3)
|
if (errored || mappedFaceIndices.size() < 3)
|
||||||
continue;
|
continue;
|
||||||
bool welded = false;
|
bool welded = false;
|
||||||
for (decltype(mappedFaceIndicies.size()) j = 0; j < mappedFaceIndicies.size(); j++) {
|
for (decltype(mappedFaceIndices.size()) j = 0; j < mappedFaceIndices.size(); j++) {
|
||||||
int next = (j + 1) % 3;
|
int next = (j + 1) % 3;
|
||||||
if (mappedFaceIndicies[j] == mappedFaceIndicies[next]) {
|
if (mappedFaceIndices[j] == mappedFaceIndices[next]) {
|
||||||
welded = true;
|
welded = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -149,14 +149,14 @@ int meshWeldSeam(void *meshlite, int meshId, float allowedSmallestDistance, cons
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
faceCountAfterWeld++;
|
faceCountAfterWeld++;
|
||||||
newFaceVertexNumAndIndices.push_back(mappedFaceIndicies.size());
|
newFaceVertexNumAndIndices.push_back(mappedFaceIndices.size());
|
||||||
for (const auto &index: mappedFaceIndicies) {
|
for (const auto &index: mappedFaceIndices) {
|
||||||
newFaceVertexNumAndIndices.push_back(index);
|
newFaceVertexNumAndIndices.push_back(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (affectedNum)
|
if (affectedNum)
|
||||||
*affectedNum = weldedCount;
|
*affectedNum = weldedCount;
|
||||||
qDebug() << "Welded" << weldedCount << "triangles(" << newFaceIndicies.size() << " - " << weldedCount << " = " << faceCountAfterWeld << ")";
|
qDebug() << "Welded" << weldedCount << "triangles(" << newFaceIndices.size() << " - " << weldedCount << " = " << faceCountAfterWeld << ")";
|
||||||
weldedMesh = meshlite_build(meshlite, vertexPositions, vertexCount, newFaceVertexNumAndIndices.data(), newFaceVertexNumAndIndices.size());
|
weldedMesh = meshlite_build(meshlite, vertexPositions, vertexCount, newFaceVertexNumAndIndices.data(), newFaceVertexNumAndIndices.size());
|
||||||
delete[] faceVertexNumAndIndices;
|
delete[] faceVertexNumAndIndices;
|
||||||
delete[] vertexPositions;
|
delete[] vertexPositions;
|
||||||
|
|
|
@ -90,7 +90,7 @@ void RigGenerator::generate()
|
||||||
const auto &sourceTriangle = m_outcome->triangles[triangleIndex];
|
const auto &sourceTriangle = m_outcome->triangles[triangleIndex];
|
||||||
MeshSplitterTriangle newTriangle;
|
MeshSplitterTriangle newTriangle;
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
newTriangle.indicies[i] = sourceTriangle[i];
|
newTriangle.indices[i] = sourceTriangle[i];
|
||||||
auto findMarkedNodeResult = markedNodes.find(triangleSourceNodes[triangleIndex]);
|
auto findMarkedNodeResult = markedNodes.find(triangleSourceNodes[triangleIndex]);
|
||||||
if (findMarkedNodeResult != markedNodes.end()) {
|
if (findMarkedNodeResult != markedNodes.end()) {
|
||||||
auto &markedNode = findMarkedNodeResult->second;
|
auto &markedNode = findMarkedNodeResult->second;
|
||||||
|
@ -188,7 +188,7 @@ void RigGenerator::generate()
|
||||||
const auto &weight = weightItem.second;
|
const auto &weight = weightItem.second;
|
||||||
int blendR = 0, blendG = 0, blendB = 0;
|
int blendR = 0, blendG = 0, blendB = 0;
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
int boneIndex = weight.boneIndicies[i];
|
int boneIndex = weight.boneIndices[i];
|
||||||
if (boneIndex > 0) {
|
if (boneIndex > 0) {
|
||||||
const auto &bone = resultBones[boneIndex];
|
const auto &bone = resultBones[boneIndex];
|
||||||
blendR += bone.color.red() * weight.boneWeights[i];
|
blendR += bone.color.red() * weight.boneWeights[i];
|
||||||
|
|
|
@ -121,7 +121,7 @@ void Rigger::addTrianglesToVertices(const std::set<MeshSplitterTriangle> &triang
|
||||||
{
|
{
|
||||||
for (const auto &triangle: triangles) {
|
for (const auto &triangle: triangles) {
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
vertices.insert(triangle.indicies[i]);
|
vertices.insert(triangle.indices[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
12
src/rigger.h
12
src/rigger.h
|
@ -52,7 +52,7 @@ private:
|
||||||
float minDistance2 = std::numeric_limits<float>::max();
|
float minDistance2 = std::numeric_limits<float>::max();
|
||||||
for (const auto &triangle: triangles) {
|
for (const auto &triangle: triangles) {
|
||||||
for (size_t i = 0; i < 3; ++i) {
|
for (size_t i = 0; i < 3; ++i) {
|
||||||
float distance2 = verticesPositions[triangle.indicies[i]].lengthSquared();
|
float distance2 = verticesPositions[triangle.indices[i]].lengthSquared();
|
||||||
if (distance2 < minDistance2)
|
if (distance2 < minDistance2)
|
||||||
minDistance2 = distance2;
|
minDistance2 = distance2;
|
||||||
}
|
}
|
||||||
|
@ -82,13 +82,13 @@ public:
|
||||||
class RiggerVertexWeights
|
class RiggerVertexWeights
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int boneIndicies[4] = {0, 0, 0, 0};
|
int boneIndices[4] = {0, 0, 0, 0};
|
||||||
float boneWeights[4] = {0, 0, 0, 0};
|
float boneWeights[4] = {0, 0, 0, 0};
|
||||||
void addBone(int boneIndex, float distance)
|
void addBone(int boneIndex, float distance)
|
||||||
{
|
{
|
||||||
if (m_boneRawIndicies.find(boneIndex) != m_boneRawIndicies.end())
|
if (m_boneRawIndices.find(boneIndex) != m_boneRawIndices.end())
|
||||||
return;
|
return;
|
||||||
m_boneRawIndicies.insert(boneIndex);
|
m_boneRawIndices.insert(boneIndex);
|
||||||
if (qFuzzyIsNull(distance))
|
if (qFuzzyIsNull(distance))
|
||||||
distance = 0.0001;
|
distance = 0.0001;
|
||||||
m_boneRawWeights.push_back(std::make_pair(boneIndex, 1.0 / distance));
|
m_boneRawWeights.push_back(std::make_pair(boneIndex, 1.0 / distance));
|
||||||
|
@ -107,7 +107,7 @@ public:
|
||||||
if (totalDistance > 0) {
|
if (totalDistance > 0) {
|
||||||
for (size_t i = 0; i < m_boneRawWeights.size() && i < 4; i++) {
|
for (size_t i = 0; i < m_boneRawWeights.size() && i < 4; i++) {
|
||||||
const auto &item = m_boneRawWeights[i];
|
const auto &item = m_boneRawWeights[i];
|
||||||
boneIndicies[i] = item.first;
|
boneIndices[i] = item.first;
|
||||||
boneWeights[i] = item.second / totalDistance;
|
boneWeights[i] = item.second / totalDistance;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -115,7 +115,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
std::set<int> m_boneRawIndicies;
|
std::set<int> m_boneRawIndices;
|
||||||
std::vector<std::pair<int, float>> m_boneRawWeights;
|
std::vector<std::pair<int, float>> m_boneRawWeights;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,14 +6,14 @@ SkinnedMeshCreator::SkinnedMeshCreator(const Outcome &outcome,
|
||||||
m_outcome(outcome),
|
m_outcome(outcome),
|
||||||
m_resultWeights(resultWeights)
|
m_resultWeights(resultWeights)
|
||||||
{
|
{
|
||||||
m_verticesOldIndicies.resize(m_outcome.triangles.size());
|
m_verticesOldIndices.resize(m_outcome.triangles.size());
|
||||||
m_verticesBindNormals.resize(m_outcome.triangles.size());
|
m_verticesBindNormals.resize(m_outcome.triangles.size());
|
||||||
m_verticesBindPositions.resize(m_outcome.triangles.size());
|
m_verticesBindPositions.resize(m_outcome.triangles.size());
|
||||||
const std::vector<std::vector<QVector3D>> *triangleVertexNormals = m_outcome.triangleVertexNormals();
|
const std::vector<std::vector<QVector3D>> *triangleVertexNormals = m_outcome.triangleVertexNormals();
|
||||||
for (size_t triangleIndex = 0; triangleIndex < m_outcome.triangles.size(); triangleIndex++) {
|
for (size_t triangleIndex = 0; triangleIndex < m_outcome.triangles.size(); triangleIndex++) {
|
||||||
for (int j = 0; j < 3; j++) {
|
for (int j = 0; j < 3; j++) {
|
||||||
int oldIndex = m_outcome.triangles[triangleIndex][j];
|
int oldIndex = m_outcome.triangles[triangleIndex][j];
|
||||||
m_verticesOldIndicies[triangleIndex].push_back(oldIndex);
|
m_verticesOldIndices[triangleIndex].push_back(oldIndex);
|
||||||
m_verticesBindPositions[triangleIndex].push_back(m_outcome.vertices[oldIndex]);
|
m_verticesBindPositions[triangleIndex].push_back(m_outcome.vertices[oldIndex]);
|
||||||
if (nullptr != triangleVertexNormals)
|
if (nullptr != triangleVertexNormals)
|
||||||
m_verticesBindNormals[triangleIndex].push_back((*triangleVertexNormals)[triangleIndex][j]);
|
m_verticesBindNormals[triangleIndex].push_back((*triangleVertexNormals)[triangleIndex][j]);
|
||||||
|
@ -44,15 +44,15 @@ MeshLoader *SkinnedMeshCreator::createMeshFromTransform(const std::vector<QMatri
|
||||||
if (!matricies.empty()) {
|
if (!matricies.empty()) {
|
||||||
for (size_t i = 0; i < transformedPositions.size(); ++i) {
|
for (size_t i = 0; i < transformedPositions.size(); ++i) {
|
||||||
for (size_t j = 0; j < 3; ++j) {
|
for (size_t j = 0; j < 3; ++j) {
|
||||||
const auto &weight = m_resultWeights[m_verticesOldIndicies[i][j]];
|
const auto &weight = m_resultWeights[m_verticesOldIndices[i][j]];
|
||||||
QMatrix4x4 mixedMatrix;
|
QMatrix4x4 mixedMatrix;
|
||||||
transformedPositions[i][j] = QVector3D();
|
transformedPositions[i][j] = QVector3D();
|
||||||
transformedPoseNormals[i][j] = QVector3D();
|
transformedPoseNormals[i][j] = QVector3D();
|
||||||
for (int x = 0; x < 4; x++) {
|
for (int x = 0; x < 4; x++) {
|
||||||
float factor = weight.boneWeights[x];
|
float factor = weight.boneWeights[x];
|
||||||
if (factor > 0) {
|
if (factor > 0) {
|
||||||
transformedPositions[i][j] += matricies[weight.boneIndicies[x]] * m_verticesBindPositions[i][j] * factor;
|
transformedPositions[i][j] += matricies[weight.boneIndices[x]] * m_verticesBindPositions[i][j] * factor;
|
||||||
transformedPoseNormals[i][j] += matricies[weight.boneIndicies[x]] * m_verticesBindNormals[i][j] * factor;
|
transformedPoseNormals[i][j] += matricies[weight.boneIndices[x]] * m_verticesBindNormals[i][j] * factor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ public:
|
||||||
private:
|
private:
|
||||||
Outcome m_outcome;
|
Outcome m_outcome;
|
||||||
std::map<int, RiggerVertexWeights> m_resultWeights;
|
std::map<int, RiggerVertexWeights> m_resultWeights;
|
||||||
std::vector<std::vector<int>> m_verticesOldIndicies;
|
std::vector<std::vector<int>> m_verticesOldIndices;
|
||||||
std::vector<std::vector<QVector3D>> m_verticesBindPositions;
|
std::vector<std::vector<QVector3D>> m_verticesBindPositions;
|
||||||
std::vector<std::vector<QVector3D>> m_verticesBindNormals;
|
std::vector<std::vector<QVector3D>> m_verticesBindNormals;
|
||||||
std::vector<QColor> m_triangleColors;
|
std::vector<QColor> m_triangleColors;
|
||||||
|
|
|
@ -28,9 +28,9 @@ void uvUnwrap(const Outcome &outcome, std::vector<std::vector<QVector2D>> &trian
|
||||||
const auto &triangle = choosenTriangles[i];
|
const auto &triangle = choosenTriangles[i];
|
||||||
const auto &sourceNode = triangleSourceNodes[i];
|
const auto &sourceNode = triangleSourceNodes[i];
|
||||||
simpleuv::Face f;
|
simpleuv::Face f;
|
||||||
f.indicies[0] = triangle[0];
|
f.indices[0] = triangle[0];
|
||||||
f.indicies[1] = triangle[1];
|
f.indices[1] = triangle[1];
|
||||||
f.indicies[2] = triangle[2];
|
f.indices[2] = triangle[2];
|
||||||
inputMesh.faces.push_back(f);
|
inputMesh.faces.push_back(f);
|
||||||
auto findPartitionResult = partIdToPartitionMap.find(sourceNode.first);
|
auto findPartitionResult = partIdToPartitionMap.find(sourceNode.first);
|
||||||
if (findPartitionResult == partIdToPartitionMap.end()) {
|
if (findPartitionResult == partIdToPartitionMap.end()) {
|
||||||
|
|
|
@ -13,7 +13,7 @@ struct Vertex
|
||||||
|
|
||||||
struct Face
|
struct Face
|
||||||
{
|
{
|
||||||
size_t indicies[3];
|
size_t indices[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TextureCoord
|
struct TextureCoord
|
||||||
|
|
|
@ -31,7 +31,7 @@ bool parametrize(const std::vector<Vertex> &verticies,
|
||||||
|
|
||||||
for (decltype(faces.size()) i = 0; i < faces.size(); i++) {
|
for (decltype(faces.size()) i = 0; i < faces.size(); i++) {
|
||||||
const auto &face = faces[i];
|
const auto &face = faces[i];
|
||||||
F.row(i) << face.indicies[0], face.indicies[1], face.indicies[2];
|
F.row(i) << face.indices[0], face.indices[1], face.indices[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the initial solution for ARAP (harmonic parametrization)
|
// Compute the initial solution for ARAP (harmonic parametrization)
|
||||||
|
|
|
@ -89,9 +89,9 @@ void triangulate(const std::vector<Vertex> &vertices, std::vector<Face> &faces,
|
||||||
}
|
}
|
||||||
if (isEar) {
|
if (isEar) {
|
||||||
Face newFace;
|
Face newFace;
|
||||||
newFace.indicies[0] = fillRing[i];
|
newFace.indices[0] = fillRing[i];
|
||||||
newFace.indicies[1] = fillRing[j];
|
newFace.indices[1] = fillRing[j];
|
||||||
newFace.indicies[2] = fillRing[k];
|
newFace.indices[2] = fillRing[k];
|
||||||
faces.push_back(newFace);
|
faces.push_back(newFace);
|
||||||
fillRing.erase(fillRing.begin() + j);
|
fillRing.erase(fillRing.begin() + j);
|
||||||
newFaceGenerated = true;
|
newFaceGenerated = true;
|
||||||
|
@ -104,9 +104,9 @@ void triangulate(const std::vector<Vertex> &vertices, std::vector<Face> &faces,
|
||||||
}
|
}
|
||||||
if (fillRing.size() == 3) {
|
if (fillRing.size() == 3) {
|
||||||
Face newFace;
|
Face newFace;
|
||||||
newFace.indicies[0] = fillRing[0];
|
newFace.indices[0] = fillRing[0];
|
||||||
newFace.indicies[1] = fillRing[1];
|
newFace.indices[1] = fillRing[1];
|
||||||
newFace.indicies[2] = fillRing[2];
|
newFace.indices[2] = fillRing[2];
|
||||||
faces.push_back(newFace);
|
faces.push_back(newFace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ void UvUnwrapper::buildEdgeToFaceMap(const std::vector<Face> &faces, std::map<st
|
||||||
const auto &face = faces[index];
|
const auto &face = faces[index];
|
||||||
for (size_t i = 0; i < 3; i++) {
|
for (size_t i = 0; i < 3; i++) {
|
||||||
size_t j = (i + 1) % 3;
|
size_t j = (i + 1) % 3;
|
||||||
edgeToFaceMap[{face.indicies[i], face.indicies[j]}] = index;
|
edgeToFaceMap[{face.indices[i], face.indices[j]}] = index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ void UvUnwrapper::buildEdgeToFaceMap(const std::vector<size_t> &group, std::map<
|
||||||
const auto &face = m_mesh.faces[index];
|
const auto &face = m_mesh.faces[index];
|
||||||
for (size_t i = 0; i < 3; i++) {
|
for (size_t i = 0; i < 3; i++) {
|
||||||
size_t j = (i + 1) % 3;
|
size_t j = (i + 1) % 3;
|
||||||
edgeToFaceMap[{face.indicies[i], face.indicies[j]}] = index;
|
edgeToFaceMap[{face.indices[i], face.indices[j]}] = index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ void UvUnwrapper::splitPartitionToIslands(const std::vector<size_t> &group, std:
|
||||||
const auto &face = m_mesh.faces[index];
|
const auto &face = m_mesh.faces[index];
|
||||||
for (size_t i = 0; i < 3; i++) {
|
for (size_t i = 0; i < 3; i++) {
|
||||||
size_t j = (i + 1) % 3;
|
size_t j = (i + 1) % 3;
|
||||||
auto findOppositeFaceResult = edgeToFaceMap.find({face.indicies[j], face.indicies[i]});
|
auto findOppositeFaceResult = edgeToFaceMap.find({face.indices[j], face.indices[i]});
|
||||||
if (findOppositeFaceResult == edgeToFaceMap.end())
|
if (findOppositeFaceResult == edgeToFaceMap.end())
|
||||||
continue;
|
continue;
|
||||||
waitFaces.push(findOppositeFaceResult->second);
|
waitFaces.push(findOppositeFaceResult->second);
|
||||||
|
@ -134,10 +134,10 @@ bool UvUnwrapper::fixHolesExceptTheLongestRing(const std::vector<Vertex> &vertic
|
||||||
for (const auto &face: faces) {
|
for (const auto &face: faces) {
|
||||||
for (size_t i = 0; i < 3; i++) {
|
for (size_t i = 0; i < 3; i++) {
|
||||||
size_t j = (i + 1) % 3;
|
size_t j = (i + 1) % 3;
|
||||||
auto findOppositeFaceResult = edgeToFaceMap.find({face.indicies[j], face.indicies[i]});
|
auto findOppositeFaceResult = edgeToFaceMap.find({face.indices[j], face.indices[i]});
|
||||||
if (findOppositeFaceResult != edgeToFaceMap.end())
|
if (findOppositeFaceResult != edgeToFaceMap.end())
|
||||||
continue;
|
continue;
|
||||||
holeVertexLink[face.indicies[j]].push_back(face.indicies[i]);
|
holeVertexLink[face.indices[j]].push_back(face.indices[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,7 +220,7 @@ bool UvUnwrapper::fixHolesExceptTheLongestRing(const std::vector<Vertex> &vertic
|
||||||
}
|
}
|
||||||
|
|
||||||
if (holeRings.size() > 1) {
|
if (holeRings.size() > 1) {
|
||||||
// Sort by ring length, the longer ring sit in the lower array indicies
|
// Sort by ring length, the longer ring sit in the lower array indices
|
||||||
std::sort(holeRings.begin(), holeRings.end(), [](const std::pair<std::vector<size_t>, double> &first, const std::pair<std::vector<size_t>, double> &second) {
|
std::sort(holeRings.begin(), holeRings.end(), [](const std::pair<std::vector<size_t>, double> &first, const std::pair<std::vector<size_t>, double> &second) {
|
||||||
return first.second > second.second;
|
return first.second > second.second;
|
||||||
});
|
});
|
||||||
|
@ -248,7 +248,7 @@ void UvUnwrapper::makeSeamAndCut(const std::vector<Vertex> &verticies,
|
||||||
for (decltype(faces.size()) i = 0; i < faces.size(); ++i) {
|
for (decltype(faces.size()) i = 0; i < faces.size(); ++i) {
|
||||||
const auto &face = faces[i];
|
const auto &face = faces[i];
|
||||||
for (int j = 0; j < 3; ++j) {
|
for (int j = 0; j < 3; ++j) {
|
||||||
const auto &vertex = verticies[face.indicies[j]];
|
const auto &vertex = verticies[face.indices[j]];
|
||||||
if (firstTime || vertex.xyz[2] > maxY) {
|
if (firstTime || vertex.xyz[2] > maxY) {
|
||||||
maxY = vertex.xyz[2];
|
maxY = vertex.xyz[2];
|
||||||
firstTime = false;
|
firstTime = false;
|
||||||
|
@ -273,7 +273,7 @@ void UvUnwrapper::makeSeamAndCut(const std::vector<Vertex> &verticies,
|
||||||
const auto &face = faces[index];
|
const auto &face = faces[index];
|
||||||
for (size_t i = 0; i < 3; i++) {
|
for (size_t i = 0; i < 3; i++) {
|
||||||
size_t j = (i + 1) % 3;
|
size_t j = (i + 1) % 3;
|
||||||
auto findOppositeFaceResult = edgeToFaceMap.find({face.indicies[j], face.indicies[i]});
|
auto findOppositeFaceResult = edgeToFaceMap.find({face.indices[j], face.indices[i]});
|
||||||
if (findOppositeFaceResult == edgeToFaceMap.end())
|
if (findOppositeFaceResult == edgeToFaceMap.end())
|
||||||
continue;
|
continue;
|
||||||
waitFaces.push(findOppositeFaceResult->second);
|
waitFaces.push(findOppositeFaceResult->second);
|
||||||
|
@ -400,12 +400,12 @@ void UvUnwrapper::unwrapSingleIsland(const std::vector<size_t> &group, bool skip
|
||||||
const auto &globalFace = m_mesh.faces[group[i]];
|
const auto &globalFace = m_mesh.faces[group[i]];
|
||||||
Face localFace;
|
Face localFace;
|
||||||
for (size_t j = 0; j < 3; j++) {
|
for (size_t j = 0; j < 3; j++) {
|
||||||
int globalVertexIndex = globalFace.indicies[j];
|
int globalVertexIndex = globalFace.indices[j];
|
||||||
if (globalToLocalVerticesMap.find(globalVertexIndex) == globalToLocalVerticesMap.end()) {
|
if (globalToLocalVerticesMap.find(globalVertexIndex) == globalToLocalVerticesMap.end()) {
|
||||||
localVertices.push_back(m_mesh.verticies[globalVertexIndex]);
|
localVertices.push_back(m_mesh.verticies[globalVertexIndex]);
|
||||||
globalToLocalVerticesMap[globalVertexIndex] = (int)localVertices.size() - 1;
|
globalToLocalVerticesMap[globalVertexIndex] = (int)localVertices.size() - 1;
|
||||||
}
|
}
|
||||||
localFace.indicies[j] = globalToLocalVerticesMap[globalVertexIndex];
|
localFace.indices[j] = globalToLocalVerticesMap[globalVertexIndex];
|
||||||
}
|
}
|
||||||
localFaces.push_back(localFace);
|
localFaces.push_back(localFace);
|
||||||
localToGlobalFacesMap[localFaces.size() - 1] = group[i];
|
localToGlobalFacesMap[localFaces.size() - 1] = group[i];
|
||||||
|
@ -455,7 +455,7 @@ void UvUnwrapper::parametrizeSingleGroup(const std::vector<Vertex> &verticies,
|
||||||
auto globalFaceIndex = localToGlobalFacesMap[i];
|
auto globalFaceIndex = localToGlobalFacesMap[i];
|
||||||
FaceTextureCoords faceUv;
|
FaceTextureCoords faceUv;
|
||||||
for (size_t j = 0; j < 3; j++) {
|
for (size_t j = 0; j < 3; j++) {
|
||||||
const auto &localVertexIndex = localFace.indicies[j];
|
const auto &localVertexIndex = localFace.indices[j];
|
||||||
const auto &vertexUv = localVertexUvs[localVertexIndex];
|
const auto &vertexUv = localVertexUvs[localVertexIndex];
|
||||||
faceUv.coords[j].uv[0] = vertexUv.uv[0];
|
faceUv.coords[j].uv[0] = vertexUv.uv[0];
|
||||||
faceUv.coords[j].uv[1] = vertexUv.uv[1];
|
faceUv.coords[j].uv[1] = vertexUv.uv[1];
|
||||||
|
|
Loading…
Reference in New Issue