Support rigging for uncombined mesh.
parent
00c05e8cb0
commit
74f5a081e3
|
@ -5,8 +5,9 @@
|
||||||
#include "animalrigger.h"
|
#include "animalrigger.h"
|
||||||
|
|
||||||
AnimalRigger::AnimalRigger(const std::vector<QVector3D> &verticesPositions,
|
AnimalRigger::AnimalRigger(const std::vector<QVector3D> &verticesPositions,
|
||||||
const std::set<MeshSplitterTriangle> &inputTriangles) :
|
const std::set<MeshSplitterTriangle> &inputTriangles,
|
||||||
Rigger(verticesPositions, inputTriangles)
|
const std::vector<std::pair<std::pair<size_t, size_t>, std::pair<size_t, size_t>>> &triangleLinks) :
|
||||||
|
Rigger(verticesPositions, inputTriangles, triangleLinks)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,8 @@ class AnimalRigger: public Rigger
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
AnimalRigger(const std::vector<QVector3D> &verticesPositions,
|
AnimalRigger(const std::vector<QVector3D> &verticesPositions,
|
||||||
const std::set<MeshSplitterTriangle> &inputTriangles);
|
const std::set<MeshSplitterTriangle> &inputTriangles,
|
||||||
|
const std::vector<std::pair<std::pair<size_t, size_t>, std::pair<size_t, size_t>>> &triangleLinks);
|
||||||
protected:
|
protected:
|
||||||
bool validate() override;
|
bool validate() override;
|
||||||
bool isCutOffSplitter(BoneMark boneMark) override;
|
bool isCutOffSplitter(BoneMark boneMark) override;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "meshsplitter.h"
|
#include "meshsplitter.h"
|
||||||
|
|
||||||
bool MeshSplitter::split(const std::set<MeshSplitterTriangle> &input,
|
bool MeshSplitter::split(const std::set<MeshSplitterTriangle> &input,
|
||||||
|
const std::vector<std::pair<std::pair<size_t, size_t>, std::pair<size_t, size_t>>> &triangleLinks,
|
||||||
std::set<MeshSplitterTriangle> &splitter,
|
std::set<MeshSplitterTriangle> &splitter,
|
||||||
std::set<MeshSplitterTriangle> &firstGroup,
|
std::set<MeshSplitterTriangle> &firstGroup,
|
||||||
std::set<MeshSplitterTriangle> &secondGroup,
|
std::set<MeshSplitterTriangle> &secondGroup,
|
||||||
|
@ -21,6 +22,22 @@ bool MeshSplitter::split(const std::set<MeshSplitterTriangle> &input,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::map<std::pair<int, int>, MeshSplitterTriangle> edgeToLinkedTriangleMap;
|
||||||
|
for (const auto &it: triangleLinks) {
|
||||||
|
auto firstEdge = std::make_pair((int)it.first.first, (int)it.first.second);
|
||||||
|
auto secondEdge = std::make_pair((int)it.second.first, (int)it.second.second);
|
||||||
|
auto findFirstTriangle = edgeToTriangleMap.find(firstEdge);
|
||||||
|
auto findSecondTriangle = edgeToTriangleMap.find(secondEdge);
|
||||||
|
if (findFirstTriangle == edgeToTriangleMap.end())
|
||||||
|
continue;
|
||||||
|
if (findSecondTriangle == edgeToTriangleMap.end())
|
||||||
|
continue;
|
||||||
|
edgeToLinkedTriangleMap[firstEdge] = findSecondTriangle->second;
|
||||||
|
edgeToLinkedTriangleMap[std::make_pair(firstEdge.second, firstEdge.first)] = findSecondTriangle->second;
|
||||||
|
edgeToLinkedTriangleMap[secondEdge] = findFirstTriangle->second;
|
||||||
|
edgeToLinkedTriangleMap[std::make_pair(secondEdge.second, secondEdge.first)] = findFirstTriangle->second;
|
||||||
|
}
|
||||||
|
|
||||||
// Expand the splitter if needed
|
// Expand the splitter if needed
|
||||||
if (expandSplitter) {
|
if (expandSplitter) {
|
||||||
std::vector<MeshSplitterTriangle> expandedTriangles;
|
std::vector<MeshSplitterTriangle> expandedTriangles;
|
||||||
|
@ -29,15 +46,13 @@ bool MeshSplitter::split(const std::set<MeshSplitterTriangle> &input,
|
||||||
int next = (i + 1) % 3;
|
int next = (i + 1) % 3;
|
||||||
auto oppositeEdge = std::make_pair(triangle.indices[next], triangle.indices[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;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (splitter.find(oppositeTriangle->second) == splitter.end()) {
|
if (splitter.find(oppositeTriangle->second) == splitter.end()) {
|
||||||
expandedTriangles.push_back(oppositeTriangle->second);
|
expandedTriangles.push_back(oppositeTriangle->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
size_t addTriangles = 0;
|
size_t addTriangles = 0;
|
||||||
for (const auto &triangle: expandedTriangles) {
|
for (const auto &triangle: expandedTriangles) {
|
||||||
auto insertResult = splitter.insert(triangle);
|
auto insertResult = splitter.insert(triangle);
|
||||||
|
@ -61,7 +76,7 @@ bool MeshSplitter::split(const std::set<MeshSplitterTriangle> &input,
|
||||||
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;
|
||||||
return false;
|
continue;
|
||||||
}
|
}
|
||||||
if (splitter.find(oppositeTriangle->second) == splitter.end()) {
|
if (splitter.find(oppositeTriangle->second) == splitter.end()) {
|
||||||
foundStartTriangle = true;
|
foundStartTriangle = true;
|
||||||
|
@ -92,14 +107,18 @@ bool MeshSplitter::split(const std::set<MeshSplitterTriangle> &input,
|
||||||
int next = (i + 1) % 3;
|
int next = (i + 1) % 3;
|
||||||
auto oppositeEdge = std::make_pair(triangle.indices[next], triangle.indices[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;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (processedTriangles.find(oppositeTriangle->second) == processedTriangles.end()) {
|
if (processedTriangles.find(oppositeTriangle->second) == processedTriangles.end()) {
|
||||||
waitQueue.push(oppositeTriangle->second);
|
waitQueue.push(oppositeTriangle->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
auto linkedTriangle = edgeToLinkedTriangleMap.find(oppositeEdge);
|
||||||
|
if (linkedTriangle != edgeToLinkedTriangleMap.end()) {
|
||||||
|
if (processedTriangles.find(linkedTriangle->second) == processedTriangles.end()) {
|
||||||
|
waitQueue.push(linkedTriangle->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now, the remains should be put in the second group
|
// Now, the remains should be put in the second group
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef DUST3D_MESH_SPLITTER_H
|
#ifndef DUST3D_MESH_SPLITTER_H
|
||||||
#define DUST3D_MESH_SPLITTER_H
|
#define DUST3D_MESH_SPLITTER_H
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class MeshSplitterTriangle
|
class MeshSplitterTriangle
|
||||||
{
|
{
|
||||||
|
@ -18,6 +19,7 @@ class MeshSplitter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static bool split(const std::set<MeshSplitterTriangle> &input,
|
static bool split(const std::set<MeshSplitterTriangle> &input,
|
||||||
|
const std::vector<std::pair<std::pair<size_t, size_t>, std::pair<size_t, size_t>>> &triangleLinks,
|
||||||
std::set<MeshSplitterTriangle> &splitter,
|
std::set<MeshSplitterTriangle> &splitter,
|
||||||
std::set<MeshSplitterTriangle> &firstGroup,
|
std::set<MeshSplitterTriangle> &firstGroup,
|
||||||
std::set<MeshSplitterTriangle> &secondGroup,
|
std::set<MeshSplitterTriangle> &secondGroup,
|
||||||
|
|
|
@ -124,6 +124,18 @@ public:
|
||||||
m_hasPartUvRects = true;
|
m_hasPartUvRects = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<std::pair<std::pair<size_t, size_t>, std::pair<size_t, size_t>>> *triangleLinks() const
|
||||||
|
{
|
||||||
|
if (!m_hasTriangleLinks)
|
||||||
|
return nullptr;
|
||||||
|
return &m_triangleLinks;
|
||||||
|
}
|
||||||
|
void setTriangleLinks(const std::vector<std::pair<std::pair<size_t, size_t>, std::pair<size_t, size_t>>> &triangleLinks)
|
||||||
|
{
|
||||||
|
m_triangleLinks = triangleLinks;
|
||||||
|
m_hasTriangleLinks = true;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_hasTriangleSourceNodes = false;
|
bool m_hasTriangleSourceNodes = false;
|
||||||
std::vector<std::pair<QUuid, QUuid>> m_triangleSourceNodes;
|
std::vector<std::pair<QUuid, QUuid>> m_triangleSourceNodes;
|
||||||
|
@ -139,6 +151,9 @@ private:
|
||||||
|
|
||||||
bool m_hasPartUvRects = false;
|
bool m_hasPartUvRects = false;
|
||||||
std::map<QUuid, std::vector<QRectF>> m_partUvRects;
|
std::map<QUuid, std::vector<QRectF>> m_partUvRects;
|
||||||
|
|
||||||
|
bool m_hasTriangleLinks = false;
|
||||||
|
std::vector<std::pair<std::pair<size_t, size_t>, std::pair<size_t, size_t>>> m_triangleLinks;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "riggenerator.h"
|
#include "riggenerator.h"
|
||||||
#include "riggerconstruct.h"
|
#include "riggerconstruct.h"
|
||||||
#include "boundingboxmesh.h"
|
#include "boundingboxmesh.h"
|
||||||
|
#include "triangleislandslink.h"
|
||||||
|
|
||||||
RigGenerator::RigGenerator(RigType rigType, const Outcome &outcome) :
|
RigGenerator::RigGenerator(RigType rigType, const Outcome &outcome) :
|
||||||
m_rigType(rigType),
|
m_rigType(rigType),
|
||||||
|
@ -141,7 +142,11 @@ void RigGenerator::generate()
|
||||||
combinedMarkedNodesList.push_back(newNodes);
|
combinedMarkedNodesList.push_back(newNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_autoRigger = newRigger(m_rigType, inputVerticesPositions, inputTriangles);
|
std::vector<std::pair<std::pair<size_t, size_t>, std::pair<size_t, size_t>>> triangleLinks;
|
||||||
|
triangleIslandsLink(*m_outcome, triangleLinks);
|
||||||
|
m_outcome->setTriangleLinks(triangleLinks);
|
||||||
|
|
||||||
|
m_autoRigger = newRigger(m_rigType, inputVerticesPositions, inputTriangles, triangleLinks);
|
||||||
if (nullptr == m_autoRigger) {
|
if (nullptr == m_autoRigger) {
|
||||||
qDebug() << "Unsupported rig type:" << RigTypeToString(m_rigType);
|
qDebug() << "Unsupported rig type:" << RigTypeToString(m_rigType);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -10,9 +10,11 @@ QString Rigger::rootBoneName = "Body";
|
||||||
//QString Rigger::firstSpineBoneName = "Spine1";
|
//QString Rigger::firstSpineBoneName = "Spine1";
|
||||||
|
|
||||||
Rigger::Rigger(const std::vector<QVector3D> &verticesPositions,
|
Rigger::Rigger(const std::vector<QVector3D> &verticesPositions,
|
||||||
const std::set<MeshSplitterTriangle> &inputTriangles) :
|
const std::set<MeshSplitterTriangle> &inputTriangles,
|
||||||
|
const std::vector<std::pair<std::pair<size_t, size_t>, std::pair<size_t, size_t>>> &triangleLinks) :
|
||||||
m_verticesPositions(verticesPositions),
|
m_verticesPositions(verticesPositions),
|
||||||
m_inputTriangles(inputTriangles),
|
m_inputTriangles(inputTriangles),
|
||||||
|
m_triangleLinks(triangleLinks),
|
||||||
m_extraMessagedAdded(false)
|
m_extraMessagedAdded(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -83,7 +85,7 @@ bool Rigger::addMarkGroup(BoneMark boneMark, SkeletonSide boneSide, QVector3D bo
|
||||||
mark.markTriangles = markTriangles;
|
mark.markTriangles = markTriangles;
|
||||||
|
|
||||||
if (isCutOffSplitter(mark.boneMark)) {
|
if (isCutOffSplitter(mark.boneMark)) {
|
||||||
if (!mark.split(m_verticesPositions, m_inputTriangles, m_maxCutOffSplitterExpandRound)) {
|
if (!mark.split(m_verticesPositions, m_inputTriangles, m_triangleLinks, m_maxCutOffSplitterExpandRound)) {
|
||||||
m_cutoffErrorItems.push_back(SkeletonSideToDispName(mark.boneSide) + " " + BoneMarkToDispName(mark.boneMark));
|
m_cutoffErrorItems.push_back(SkeletonSideToDispName(mark.boneSide) + " " + BoneMarkToDispName(mark.boneMark));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,13 +27,14 @@ public:
|
||||||
{
|
{
|
||||||
return m_isFirstBiggerThenSecond ? m_secondGroup : m_firstGroup;
|
return m_isFirstBiggerThenSecond ? m_secondGroup : m_firstGroup;
|
||||||
}
|
}
|
||||||
bool split(const std::vector<QVector3D> &verticesPositions, const std::set<MeshSplitterTriangle> &input, int expandRound=0)
|
bool split(const std::vector<QVector3D> &verticesPositions, const std::set<MeshSplitterTriangle> &input,
|
||||||
|
const std::vector<std::pair<std::pair<size_t, size_t>, std::pair<size_t, size_t>>> &triangleLinks, int expandRound=0)
|
||||||
{
|
{
|
||||||
int totalRound = 1 + expandRound;
|
int totalRound = 1 + expandRound;
|
||||||
for (int round = 0; round < totalRound; ++round) {
|
for (int round = 0; round < totalRound; ++round) {
|
||||||
m_firstGroup.clear();
|
m_firstGroup.clear();
|
||||||
m_secondGroup.clear();
|
m_secondGroup.clear();
|
||||||
bool splitResult = MeshSplitter::split(input, markTriangles, m_firstGroup, m_secondGroup, round > 0);
|
bool splitResult = MeshSplitter::split(input, triangleLinks, markTriangles, m_firstGroup, m_secondGroup, round > 0);
|
||||||
if (splitResult) {
|
if (splitResult) {
|
||||||
sortByDistanceFromOrigin(verticesPositions);
|
sortByDistanceFromOrigin(verticesPositions);
|
||||||
return true;
|
return true;
|
||||||
|
@ -125,7 +126,8 @@ class Rigger : public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
Rigger(const std::vector<QVector3D> &verticesPositions,
|
Rigger(const std::vector<QVector3D> &verticesPositions,
|
||||||
const std::set<MeshSplitterTriangle> &inputTriangles);
|
const std::set<MeshSplitterTriangle> &inputTriangles,
|
||||||
|
const std::vector<std::pair<std::pair<size_t, size_t>, std::pair<size_t, size_t>>> &triangleLinks);
|
||||||
bool addMarkGroup(BoneMark boneMark, SkeletonSide boneSide, QVector3D bonePosition, float nodeRadius, const std::set<MeshSplitterTriangle> &markTriangles);
|
bool addMarkGroup(BoneMark boneMark, SkeletonSide boneSide, QVector3D bonePosition, float nodeRadius, const std::set<MeshSplitterTriangle> &markTriangles);
|
||||||
const std::vector<std::pair<QtMsgType, QString>> &messages();
|
const std::vector<std::pair<QtMsgType, QString>> &messages();
|
||||||
const std::vector<RiggerBone> &resultBones();
|
const std::vector<RiggerBone> &resultBones();
|
||||||
|
@ -155,6 +157,7 @@ protected:
|
||||||
std::vector<std::pair<QtMsgType, QString>> m_messages;
|
std::vector<std::pair<QtMsgType, QString>> m_messages;
|
||||||
std::vector<QVector3D> m_verticesPositions;
|
std::vector<QVector3D> m_verticesPositions;
|
||||||
std::set<MeshSplitterTriangle> m_inputTriangles;
|
std::set<MeshSplitterTriangle> m_inputTriangles;
|
||||||
|
std::vector<std::pair<std::pair<size_t, size_t>, std::pair<size_t, size_t>>> m_triangleLinks;
|
||||||
std::vector<RiggerMark> m_marks;
|
std::vector<RiggerMark> m_marks;
|
||||||
std::map<std::pair<BoneMark, SkeletonSide>, std::vector<int>> m_marksMap;
|
std::map<std::pair<BoneMark, SkeletonSide>, std::vector<int>> m_marksMap;
|
||||||
std::vector<RiggerBone> m_resultBones;
|
std::vector<RiggerBone> m_resultBones;
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
#include "animalrigger.h"
|
#include "animalrigger.h"
|
||||||
|
|
||||||
Rigger *newRigger(RigType rigType, const std::vector<QVector3D> &verticesPositions,
|
Rigger *newRigger(RigType rigType, const std::vector<QVector3D> &verticesPositions,
|
||||||
const std::set<MeshSplitterTriangle> &inputTriangles)
|
const std::set<MeshSplitterTriangle> &inputTriangles,
|
||||||
|
const std::vector<std::pair<std::pair<size_t, size_t>, std::pair<size_t, size_t>>> &triangleLinks)
|
||||||
{
|
{
|
||||||
if (rigType == RigType::Animal)
|
if (rigType == RigType::Animal)
|
||||||
return new AnimalRigger(verticesPositions, inputTriangles);
|
return new AnimalRigger(verticesPositions, inputTriangles, triangleLinks);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
|
@ -5,6 +5,7 @@
|
||||||
#include "poser.h"
|
#include "poser.h"
|
||||||
|
|
||||||
Rigger *newRigger(RigType rigType, const std::vector<QVector3D> &verticesPositions,
|
Rigger *newRigger(RigType rigType, const std::vector<QVector3D> &verticesPositions,
|
||||||
const std::set<MeshSplitterTriangle> &inputTriangles);
|
const std::set<MeshSplitterTriangle> &inputTriangles,
|
||||||
|
const std::vector<std::pair<std::pair<size_t, size_t>, std::pair<size_t, size_t>>> &triangleLinks);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -140,31 +140,30 @@ static bool fetchCgalMeshCenter(CgalMesh *cgalMesh, QVector3D ¢er)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t findNearestTriangle(const Outcome &outcome,
|
static std::pair<size_t, size_t> findNearestTriangleEdge(const Outcome &outcome,
|
||||||
const std::vector<size_t> &group,
|
const std::vector<size_t> &group,
|
||||||
const QVector3D &point)
|
const QVector3D &point)
|
||||||
{
|
{
|
||||||
float minLength2 = std::numeric_limits<float>::max();
|
float minLength2 = std::numeric_limits<float>::max();
|
||||||
size_t choosenIndex = 0;
|
std::pair<size_t, size_t> choosenEdge = std::make_pair(0, 0);
|
||||||
for (const auto &triangleIndex: group) {
|
for (const auto &triangleIndex: group) {
|
||||||
QVector3D sumOfPositions;
|
|
||||||
const auto &indices = outcome.triangles[triangleIndex];
|
const auto &indices = outcome.triangles[triangleIndex];
|
||||||
for (const auto &it: indices) {
|
for (size_t i = 0; i < indices.size(); ++i) {
|
||||||
sumOfPositions += outcome.vertices[it];
|
size_t j = (i + 1) % indices.size();
|
||||||
}
|
QVector3D edgeMiddle = (outcome.vertices[indices[i]] + outcome.vertices[indices[j]]) / 2;
|
||||||
QVector3D triangleCenter = sumOfPositions / indices.size();
|
float length2 = (point - edgeMiddle).lengthSquared();
|
||||||
float length2 = (point - triangleCenter).lengthSquared();
|
|
||||||
if (length2 < minLength2) {
|
if (length2 < minLength2) {
|
||||||
minLength2 = length2;
|
minLength2 = length2;
|
||||||
choosenIndex = triangleIndex;
|
choosenEdge = std::make_pair(indices[i], indices[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return choosenIndex;
|
}
|
||||||
|
return choosenEdge;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mergeIntersectedConvexMeshesAndLinkTriangles(const Outcome &outcome,
|
static bool mergeIntersectedConvexMeshesAndLinkTriangles(const Outcome &outcome,
|
||||||
std::map<QString, std::pair<CgalMesh *, std::vector<size_t>>> &convexMeshes,
|
std::map<QString, std::pair<CgalMesh *, std::vector<size_t>>> &convexMeshes,
|
||||||
std::vector<std::pair<size_t, size_t>> &links)
|
std::vector<std::pair<std::pair<size_t, size_t>, std::pair<size_t, size_t>>> &links)
|
||||||
{
|
{
|
||||||
if (convexMeshes.size() <= 1)
|
if (convexMeshes.size() <= 1)
|
||||||
return false;
|
return false;
|
||||||
|
@ -181,8 +180,8 @@ static bool mergeIntersectedConvexMeshesAndLinkTriangles(const Outcome &outcome,
|
||||||
QString secondGroupName = it.first;
|
QString secondGroupName = it.first;
|
||||||
std::vector<size_t> firstGroupTriangleIndices = head.second.second;
|
std::vector<size_t> firstGroupTriangleIndices = head.second.second;
|
||||||
std::vector<size_t> secondGroupTriangleIndices = it.second.second;
|
std::vector<size_t> secondGroupTriangleIndices = it.second.second;
|
||||||
size_t firstGroupChoosenIndex = findNearestTriangle(outcome, firstGroupTriangleIndices, center);
|
std::pair<size_t, size_t> firstGroupChoosenIndex = findNearestTriangleEdge(outcome, firstGroupTriangleIndices, center);
|
||||||
size_t secondGroupChoosenIndex = findNearestTriangle(outcome, secondGroupTriangleIndices, center);
|
std::pair<size_t, size_t> secondGroupChoosenIndex = findNearestTriangleEdge(outcome, secondGroupTriangleIndices, center);
|
||||||
links.push_back(std::make_pair(firstGroupChoosenIndex, secondGroupChoosenIndex));
|
links.push_back(std::make_pair(firstGroupChoosenIndex, secondGroupChoosenIndex));
|
||||||
std::vector<size_t> triangleIndices(firstGroupTriangleIndices);
|
std::vector<size_t> triangleIndices(firstGroupTriangleIndices);
|
||||||
triangleIndices.insert(triangleIndices.end(), secondGroupTriangleIndices.begin(), secondGroupTriangleIndices.end());
|
triangleIndices.insert(triangleIndices.end(), secondGroupTriangleIndices.begin(), secondGroupTriangleIndices.end());
|
||||||
|
@ -201,7 +200,7 @@ static bool mergeIntersectedConvexMeshesAndLinkTriangles(const Outcome &outcome,
|
||||||
}
|
}
|
||||||
|
|
||||||
void triangleIslandsLink(const Outcome &outcome,
|
void triangleIslandsLink(const Outcome &outcome,
|
||||||
std::vector<std::pair<size_t, size_t>> &links)
|
std::vector<std::pair<std::pair<size_t, size_t>, std::pair<size_t, size_t>>> &links)
|
||||||
{
|
{
|
||||||
std::vector<size_t> group;
|
std::vector<size_t> group;
|
||||||
std::vector<std::vector<size_t>> islands;
|
std::vector<std::vector<size_t>> islands;
|
||||||
|
|
|
@ -4,6 +4,6 @@
|
||||||
#include "outcome.h"
|
#include "outcome.h"
|
||||||
|
|
||||||
void triangleIslandsLink(const Outcome &outcome,
|
void triangleIslandsLink(const Outcome &outcome,
|
||||||
std::vector<std::pair<size_t, size_t>> &links);
|
std::vector<std::pair<std::pair<size_t, size_t>, std::pair<size_t, size_t>>> &links);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue